skyline TEP学习心得(2):一些常用的三维计算数学方法
由于skyline的功能并不强大,经常会遇到一些坐标的运算需要自己实现
PS:以下的类TDPoint代表一个点,有属性X,Y,Z
1.由X,Y,Z,yaw,pitch,height(长度)表达的三维线段转为两个三维点表达
public static void LineTo3DPoints(double X, double Y, double Z, double Yaw, double Pitch, double height, ref TDPoint tTDPoint1, ref TDPoint tTDPoint2)
{
tTDPoint1 = new TDPoint(X, Y, Z);
double x2 = height * Math.Sin(Yaw * Math.PI / 180) + X;
double y2 = height * Math.Cos(Yaw * Math.PI / 180) + Y;
double z2 = Math.Atan((Math.Abs(Pitch) - 90) * -1) * (x2 - X) + Z;
tTDPoint2 = new TDPoint(x2, y2, z2);
}
2.两点距离(三维)
public static double TwoPointDistance(TDPoint tPoint1, TDPoint tPoint2)
{
return Math.Sqrt(Math.Pow(tPoint1.X - tPoint2.X, 2) + Math.Pow(tPoint1.Y - tPoint2.Y, 2) + Math.Pow(tPoint1.Z - tPoint2.Z, 2));
}
3.两点距离(二维)
public static double TwoPointDistance(TDPoint tPoint1, TDPoint tPoint2)
{
return Math.Sqrt(Math.Pow(tPoint1.X - tPoint2.X, 2) + Math.Pow(tPoint1.Y - tPoint2.Y, 2));
}
4.两线段是否相交(二维)
public static bool TwoLineIsIntersect(TDPoint tTDPoint1Start, TDPoint tTDPoint1End, TDPoint tTDPoint2Start, TDPoint tTDPoint2End)
{
if (tTDPoint1Start == null || tTDPoint1End == null || tTDPoint2Start == null || tTDPoint2End == null) return false;
double A = tTDPoint1End.Y - tTDPoint1Start.Y;
double B = tTDPoint1End.X - tTDPoint1Start.X;
double C = A * tTDPoint1Start.X - B * tTDPoint1Start.Y;
double res1 = A * tTDPoint2Start.X - B * tTDPoint2Start.Y - C;
double res2 = A * tTDPoint2End.X - B * tTDPoint2End.Y - C;
if ((res1 > 0 && res2 > 0) || (res1 < 0 && res2 < 0))
{
return false;
}
A = tTDPoint2End.Y - tTDPoint2Start.Y;
B = tTDPoint2End.X - tTDPoint2Start.X;
C = A * tTDPoint2Start.X - B * tTDPoint2Start.Y;
res1 = A * tTDPoint1Start.X - B * tTDPoint1Start.Y - C;
res2 = A * tTDPoint1End.X - B * tTDPoint1End.Y - C;
if ((res1 > 0 && res2 > 0) || (res1 < 0 && res2 < 0))
{
return false;
}
return true;
}
5.求多边形重心(二维)
public static TDPoint GetPolygonZX(List<TDPoint> tPoints)
{
double area = 0;
TDPoint center = new TDPoint();
center.X = 0;
center.Y = 0;
int n = tPoints.Count;
for (int i = 0; i < tPoints.Count - 1; i++)
{
area += (tPoints[i].X * tPoints[i + 1].Y - tPoints[i + 1].X * tPoints[i].Y) / 2;
center.X += (tPoints[i].X * tPoints[i + 1].Y - tPoints[i + 1].X * tPoints[i].Y) * (tPoints[i].X + tPoints[i + 1].X);
center.Y += (tPoints[i].X * tPoints[i + 1].Y - tPoints[i + 1].X * tPoints[i].Y) * (tPoints[i].Y + tPoints[i + 1].Y);
}
area += (tPoints[n - 1].X * tPoints[0].Y - tPoints[0].X * tPoints[n - 1].Y) / 2;
center.X += (tPoints[n - 1].X * tPoints[0].Y - tPoints[0].X * tPoints[n - 1].Y) * (tPoints[n - 1].X + tPoints[0].X);
center.Y += (tPoints[n - 1].X * tPoints[0].Y - tPoints[0].X * tPoints[n - 1].Y) * (tPoints[n - 1].Y + tPoints[0].Y);
center.X /= 6 * area;
center.Y /= 6 * area;
return center;
}
6.三维线段由两个三维点的表达方式转为X,Y,Z,yaw,pitch,height(跟1是相反)
这方法还缺了height(长度的计算),可以用2计算三维两点距离来实现
S_XValue是起点X坐标,E_YValue是终点Y坐标,如此类推
public static void CalculateYawPitchRoll(double S_XValue, double S_YValue, double E_XValue, double E_YValue, double S_HIGHValue, double E_HIGHValue,
out double yaw, out double pitch)
{
double vectorXY_X = E_XValue - S_XValue;
double vectorXY_Y = E_YValue - S_YValue;
//计算yaw
yaw = Math.Atan2(vectorXY_X, vectorXY_Y) * 180 / Math.PI;
double vectorXZ_X = E_XValue - S_XValue;
double vectorXZ_Z = E_HIGHValue - S_HIGHValue;
//计算pitch
pitch = Math.Atan2(-Math.Sqrt(Math.Pow(vectorXY_X, 2) + Math.Pow(vectorXY_Y, 2)), vectorXZ_Z) * 180 / Math.PI;
}
浙公网安备 33010602011771号