c#(WinForm)绘制两个圆的内公切线

一图胜千言

在这里插入图片描述

基础知识,三角函数,反三角函数,点绕点旋转,可以看到斜率为0的情况也是进行了处理的,在运动中也没有任何BUG。当然我会放上一张图帮助大家理解。

在这里插入图片描述

核心代码

 /// <summary>
        /// 计算两个相离的圆的内公切线。(相交没有内公切线,只有外公切线)
        /// 圆C1, 圆心(a, b), 半径r1.
        /// 圆C2, 圆心(c, d), 半径r2.
        /// </summary>
        /// <returns>返回两条内公切线段,线段的两个端点是圆上的切点。</returns>
        PointF r2_low_point = new PointF();
        PointF r2_up_point = new PointF();
        PointF r1_up_point = new PointF();
        PointF r1_low_point = new PointF();
        public void getTangentPoint(double a, double b, double r1, double c, double d, double r2)
        {
            double α =Math.Atan2((b - d) , (a - c));    //求中两个圆心连线的斜率角度
            double centerLine;
            if (d == b)                            //处理斜率为零的情况       
            {
                if (a < c)
                {
                    centerLine = a - c;

                }
                else
                {
                    centerLine = c-a;
                }
            }
            else
            {
                centerLine = (d - b) / Math.Sin(α); //求两个圆心连线长度
            }
            double β = Math.Acos((r1 + r2) / centerLine);  //求两个圆心连线和圆心到切点垂线的夹角
            double θ = β - α;                              
            double r2LowX = r2 * Math.Cos(θ);
            double r2LowY = r2 * Math.Sin(θ);
            double r1UpX = r1 * Math.Cos(θ);
            double r1UpY = r1 * Math.Sin(θ);
            r2_low_point.X = centerOfCircle2.X - (float)r2LowX;
            r2_low_point.Y = centerOfCircle2.Y + (float)r2LowY;
            r1_up_point.X = centerOfCircle1.X + (float)r1UpX;
            r1_up_point.Y = centerOfCircle1.Y - (float)r1UpY;
            PointF r2_tempoint= Transition( r2_low_point.X- centerOfCircle2.X, r2_low_point.Y-centerOfCircle2.Y, 2 * β, 1);
            r2_up_point.X = centerOfCircle2.X + r2_tempoint.X;
            r2_up_point.Y = centerOfCircle2.Y + r2_tempoint.Y;
            PointF r1_tempoint = Transition(r1_up_point.X - centerOfCircle1.X, r1_up_point.Y-centerOfCircle1.Y, 2 * β, 1);
            r1_low_point.X = centerOfCircle1.X + r1_tempoint.X;
            r1_low_point.Y = centerOfCircle1.Y + r1_tempoint.Y;
        }
        //点绕点旋转
        private PointF Transition(float _x, float _y, double _angle, int fx)
        {
            double newX = 0;
            double newY = 0;
            if (fx == 1)
            {
                newX = _x * Math.Cos(_angle) - _y * Math.Sin(_angle);
                newY = _x * Math.Sin(_angle) + _y * Math.Cos(_angle);
            }
            else
            {
                newX = _x * Math.Cos(_angle) + _y * Math.Sin(_angle);
                newY = _y * Math.Cos(_angle) - _x * Math.Sin(_angle);
            }
            return new PointF((float)newX, (float)newY); 
        }
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

x县豆瓣酱

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值