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

 

posted @ 2012-07-30 14:48  cannel  阅读(876)  评论(0编辑  收藏  举报