Qt Qml Map-地图绘制两个圆的内外公切线

https://download.csdn.net/download/qq_38159549/89860109icon-default.png?t=O83Ahttps://download.csdn.net/download/qq_38159549/89860109

根据两个圆的顺逆方向决定绘制哪一条切线:

圆1顺 - 圆2顺,绘制外切线

圆1顺 - 圆2逆,绘制内切线

圆1逆 - 圆2顺,绘制内切线

圆1逆 - 圆2逆,绘制外切线

总结:旋转方向一致,绘制外公切线,反之绘制内公切线。

每两个圆都有两条内切线或者两条外切线,再根据第二个圆的顺逆方向决定绘制哪一条切线。

    /**
     * @brief 根据圆1与圆2的圆心坐标、半径、顺逆方向绘制内外公切线
     */
function calculateTangentPoints(c1, r1, direction1, c2, r2, direction2) {
        // 确定较大和较小的圆
        var largeCircle, smallCircle, largeRadius, smallRadius, largeDirection, smallDirection;
        if (r1 >= r2) {
            largeCircle = c1;
            smallCircle = c2;
            largeRadius = r1;
            smallRadius = r2;
            largeDirection = direction1;
            smallDirection = direction2;
        } else {
            largeCircle = c2;
            smallCircle = c1;
            largeRadius = r2;
            smallRadius = r1;
            largeDirection = direction2;
            smallDirection = direction1;
        }

        // 计算两圆心之间的方位角和距离
        var doubleCircle_azimuth = largeCircle.azimuthTo(smallCircle);
        var centerDist = largeCircle.distanceTo(smallCircle);

        // 确保圆心距离大于半径之差
        if (centerDist <= Math.abs(largeRadius - smallRadius)) {
            console.log("Error: 圆心距离小于半径.");
            // 清空外切线
            crosspointLineItem_ccw.path = [];
            crosspointLineItem_cw.path = [];
            // 清空内切线
            innerTangentLineItem1.path = [];
            innerTangentLineItem2.path = [];
            return;
        }

        // 判断圆1和圆2的顺逆方向是否一致
        var directionMatch = (largeDirection === smallDirection);
        console.log("directionMatch", directionMatch)

        // --------------------- 外切线 ---------------------
        if (directionMatch) {
            console.log("[绘制外切线]", direction1, direction2)
            var angleRadians = Math.acos(Math.abs(largeRadius - smallRadius) / centerDist);
            var angleDegrees = angleRadians * (180 / Math.PI);

            // 第二个圆为顺时针
            if(direction2) {
                var _LeftCrosspoint_cw = largeCircle.atDistanceAndAzimuth(largeRadius, angleDegrees + doubleCircle_azimuth);
                var _RightCrosspoint_cw = smallCircle.atDistanceAndAzimuth(smallRadius, angleDegrees + doubleCircle_azimuth);

                // 绘制外公切线
                crosspointLineItem_cw.path = [_LeftCrosspoint_cw, _RightCrosspoint_cw]
            }
            // 第二个圆为逆时针
            else {
                var _leftCrosspoint = largeCircle.atDistanceAndAzimuth(largeRadius, 90 - angleDegrees + (doubleCircle_azimuth - 90) )
                var _RightCrosspoint = smallCircle.atDistanceAndAzimuth(smallRadius, (180 - angleDegrees - 90) + (doubleCircle_azimuth - 90) )

                // 绘制外公切线
                crosspointLineItem_ccw.path = [_leftCrosspoint, _RightCrosspoint]
            }

            // 清空内切线
            innerTangentLineItem1.path = [];
            innerTangentLineItem2.path = [];
        }
        // --------------------- 内切线 ---------------------
        else {
            console.log("[绘制内切线]", direction1, direction2)
            var innerAngleRadians = Math.acos((largeRadius + smallRadius) / centerDist);
            var innerAngleDegrees = innerAngleRadians * (180 / Math.PI);

            // 内公切线角度
            var innerAngle1 = doubleCircle_azimuth + innerAngleDegrees;
            var innerAngle2 = doubleCircle_azimuth - innerAngleDegrees;

            // 第二个圆为顺时针
            if(direction2) {
                var innerTangentPoint1Large = largeCircle.atDistanceAndAzimuth(largeRadius, innerAngle1);
                var innerTangentPoint1Small = smallCircle.atDistanceAndAzimuth(smallRadius, innerAngle1 + 180);

                // 绘制内公切线
                innerTangentLineItem1.path = [innerTangentPoint1Large, innerTangentPoint1Small];
            }
            // 第二个圆为逆时针
            else {
                var innerTangentPoint2Large = largeCircle.atDistanceAndAzimuth(largeRadius, innerAngle2);
                var innerTangentPoint2Small = smallCircle.atDistanceAndAzimuth(smallRadius, innerAngle2 + 180);

                // 绘制内公切线
                innerTangentLineItem2.path = [innerTangentPoint2Large, innerTangentPoint2Small];
            }

            // 清空外切线
            crosspointLineItem_ccw.path = [];
            crosspointLineItem_cw.path = [];
        }
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值