已知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;
}