C#——圆外一点,求其切点

已知C点坐标、圆心坐标O及其半径r,求切点坐标。

我只计算了其中一个坐标点。

        float radius;//半径
        Vector3 m_yuanxin;//圆心坐标
        Vector3 m_qiedian;//切点坐标
        /// <param name="m_pos[2]">C(圆外一点)</param>
        /// <param name="Odian">O圆心坐标</param>
        /// <param name="Ddian">D切点</param>
        /// <returns></returns>
        void CalculateD(List<Vector3> ve)
        {
            // 计算OA与OD之间的夹角
            float aod;
            float l_AO = Mathf.Sqrt((ve[2].x - m_yuanxin.x) * (ve[2].x - m_yuanxin.x) + (ve[2].y - m_yuanxin.y) * (ve[2].y - m_yuanxin.y));
            aod = Mathf.Acos(radius / l_AO) * 180 / Mathf.PI;
            // 计算X轴与OA之间的角度
            float angle = 0;
            float angleend = 0;
            float _x = ve[2].x - m_yuanxin.x;
            if (ve[2].x <= m_yuanxin.x && ve[2].y >= m_yuanxin.y)//180-270;C点相对于O点在第二象限,则D点在第三象限
            {
                angle = Mathf.Acos(-_x / l_AO) * 180 / Mathf.PI;
                angleend = -180 + aod - angle;
            }
            else if (ve[2].x >= m_yuanxin.x && ve[2].y >= m_yuanxin.y)//90-180;C点相对于O点在第一象限,则D点在第二象限
            {
                angle = Mathf.Acos(_x / l_AO) * 180 / Mathf.PI;
                angleend = angle + aod;
            }
            else if (ve[2].x >= m_yuanxin.x && ve[2].y <= m_yuanxin.y)//0-90;C点相对于O点在第四象限,则D点在第一象限
            {
                angle = Mathf.Acos(_x / l_AO) * 180 / Mathf.PI;
                angleend = aod - angle;
            }
            else if (ve[2].x <= m_yuanxin.x && ve[2].y <= m_yuanxin.y)//270-360;C点相对于O点在第三象限,则D点在第四象限
            {
                angle = Mathf.Acos(-_x / l_AO) * 180 / Mathf.PI;
                angleend = angle + aod - 180;
            }
            //计算切点坐标
            float x = m_yuanxin.x + radius * Mathf.Cos(angleend * Mathf.PI / 180);
            float y = m_yuanxin.y + radius * Mathf.Sin(angleend * Mathf.PI / 180);
            m_qiedian = new Vector3(x, y, 0);
        }

以下方法是参考别个修改了点点

        /// <summary>
        /// 计算出切点坐标
        /// </summary>
        /// <param name="ptCenter">圆心坐标</param>
        /// <param name="ptOutside">第三点坐标</param>
        /// <param name="dbRadious">半径</param>
        /// <returns></returns>
        Vector3 CalcQieDian(Vector3 ptCenter, Vector3 ptOutside, float dbRadious)
        {

            Vector3 E, F, G, H;
            E = new Vector3();
            F = new Vector3();
            G = new Vector3();
            H = new Vector3();
            float r = dbRadious;
            //1. 坐标平移到圆心ptCenter处,求园外点的新坐标E
            E.x = ptOutside.x - ptCenter.x;
            E.y = ptOutside.y - ptCenter.y; //平移变换到E

            //2. 求圆与OE的交点坐标F, 相当于E的缩放变换
            float t = r / Mathf.Sqrt(E.x * E.x + E.y * E.y); //得到缩放比例
            F.x = E.x * t;
            F.y = E.y * t; //缩放变换到F

            //3. 将E旋转变换角度a到切点G,其中cos(a)=r/OF=t, 所以a=arccos(t);
            float a = Mathf.Acos(t); //得到旋转角度
            if ((E.x <= 0 && E.y >= 0) || (E.x <= 0 && E.y <= 0))//C点相对于圆心在第二、三象限
            {
                a = -a;
            }
            G.x = F.x * Mathf.Cos(a) - F.y * Mathf.Sin(a);
            G.y = F.x * Mathf.Sin(a) + F.y * Mathf.Cos(a); //旋转变换到G

            //4. 将G平移到原来的坐标下得到新坐标H
            H.x = G.x + ptCenter.x;
            H.y = G.y + ptCenter.y; //平移变换到H
            return H;
        }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值