Example #1
0
        //计算由a,b,c三点组成的向量 abxac的叉积,注:此处只是返回标量(平行四边形面积)并非实际意义上的叉积
        static public double Cross(Vector2_DW ptA, Vector2_DW ptB, Vector2_DW ptC)
        {
            Vector2_DW ab = ptB - ptA; // new Vector2_DW(b.X - a.X, b.Y - a.Y);
            Vector2_DW ac = ptC - ptA; // new Vector2_DW(c.X - a.X, c.Y - a.Y);

            return(ab.X * ac.Y - ac.X * ab.Y);
        }
Example #2
0
        static public Vector2_DW Max(Vector2_DW lhs, Vector2_DW rhs)
        {
            double x = Math.Max(lhs.X, rhs.X);
            double y = Math.Max(lhs.Y, rhs.Y);

            return(new Vector2_DW(x, y));
        }
Example #3
0
        /// <summary>
        /// ///计算pos到直线(lineSt, lineEnd)的最短距离
        /// </summary>
        /// <param name="pos"></param>
        /// <param name="lineSt"></param>
        /// <param name="lineEnd"></param>
        /// <param name="lineIsSegment">是否为线段</param>
        /// <returns></returns>
        public static double LinePointDistance(Vector2_DW lineSt, Vector2_DW lineEnd, Vector2_DW pos, bool lineIsSegment)
        {
            double disRet = 0;

            if (lineIsSegment == false)
            {
                disRet = Vector2_DW.Cross(lineSt, lineEnd, pos) / Vector2_DW.Distance(lineSt, lineEnd);
            }
            else
            {
                Vector2_DW ab = lineEnd - lineSt;
                Vector2_DW bc = pos - lineEnd;
                Vector2_DW ac = pos - lineSt;

                if (Vector2_DW.Dot(ab, bc) > 0)//pos在lineEnd外侧
                {
                    disRet = Vector2_DW.Distance(pos, lineEnd);
                }
                else if (Vector2_DW.Dot(ab, ac) > 0)//pos在lineEnd外侧
                {
                    disRet = Vector2_DW.Distance(pos, lineSt);
                }
                else//pos在lineSt与lineEnd之间
                {
                    disRet = Vector2_DW.Cross(lineSt, lineEnd, pos) / Vector2_DW.Distance(lineSt, lineEnd);
                }
            }
            return(Math.Abs(disRet));
        }
Example #4
0
        public Vector2_DW Scale(Vector2_DW size)
        {
            Vector2_DW ptRet = new Vector2_DW();

            this.X *= size.X;
            this.Y *= size.Y;
            return(ptRet);
        }
Example #5
0
        static public Vector2_DW operator +(Vector2_DW lhs, Vector2_DW rhs)
        {
            Vector2_DW result = lhs;

            result.X += rhs.X;
            result.Y += rhs.Y;
            return(result);
        }
Example #6
0
        static public Vector2_DW operator -(Vector2_DW rhs)
        {
            Vector2_DW result = new Vector2_DW();

            result.X = -rhs.X;
            result.Y = -rhs.Y;
            return(result);
        }
Example #7
0
        static public Vector2_DW operator *(double d, Vector2_DW rhs)
        {
            Vector2_DW result = new Vector2_DW();

            result.X = d * rhs.X;
            result.Y = d * rhs.Y;
            return(result);
        }
Example #8
0
        static public Vector2_DW operator *(Vector2_DW lhs, double d)
        {
            Vector2_DW result = new Vector2_DW();

            result.X = d * lhs.X;
            result.Y = d * lhs.Y;
            return(result);
        }
Example #9
0
        //获取直线的最小包围盒(传入的点的坐标为屏幕坐标)
        public static Box2D GetLineMinBox(Vector2_DW screenPtSt, Vector2_DW screenPtEnd)
        {
            Box2D bxRet = new Box2D();

            bxRet._min = Vector2_DW.Min(screenPtSt, screenPtEnd);
            bxRet._max = Vector2_DW.Max(screenPtSt, screenPtEnd);
            return(bxRet);
        }
Example #10
0
        public Vector2_DW Move(Vector2_DW basePt, Vector2_DW desPt)
        {
            Vector2_DW ptRet     = new Vector2_DW();
            Vector2_DW vecOffset = desPt - basePt;

            ptRet = this + vecOffset;
            return(ptRet);
        }
Example #11
0
        public Vector2_DW Rotate(Vector2_DW ptBase, double angleDegree)
        {
            Vector2_DW ptRet       = new Vector2_DW();
            Vector2_DW vec         = this - ptBase;
            double     angleRadium = ToolsMath_DW.Angle2Radium(angleDegree);
            double     xOffset     = (vec.X * Math.Cos(angleRadium) - vec.Y * Math.Sin(angleRadium));
            double     yOffset     = (vec.X * Math.Sin(angleRadium) + vec.Y * Math.Cos(angleRadium));

            ptRet = ptBase + new Vector2_DW(xOffset, yOffset);
            return(ptRet);
        }
Example #12
0
        public Vector2_DW Mirror(Vector2_DW lineSt, Vector2_DW lineEnd)
        {
            Vector2_DW ptRet       = new Vector2_DW();
            Vector2_DW vecPer      = (lineSt - lineEnd);
            Vector2_DW vec         = new Vector2_DW(-vecPer.Y, vecPer.X);
            Vector2_DW ptTmp       = new Vector2_DW(this + vec);
            Vector2_DW ptIntersect = new Vector2_DW();

            if (ToolsMath_DW.LineXLine(this, ptTmp, lineSt, lineEnd, ref ptIntersect) != LineIntersectType.None)
            {
                ptRet = ptIntersect + ptIntersect - this;
            }
            return(ptRet);
        }
Example #13
0
 static public bool PtInBox(Box2D bx, Vector2_DW posScreen)//判断某一点是否在包围盒内
 {
     if (posScreen.X > bx._min.X &&
         posScreen.X < bx._max.X &&
         posScreen.Y > bx._min.Y &&
         posScreen.Y < bx._max.Y)
     {
         return(true);
     }
     else
     {
         return(false);
     }
 }
Example #14
0
        /// <summary>
        /// 判断点pt是否在直线上
        /// </summary>
        /// <param name="pt"></param>
        /// <param name="lnSt"></param>
        /// <param name="lnEnd"></param>
        /// <param name="isSegment">是否为直线段</param>
        /// <returns></returns>
        public static bool IsPointOnLine(Vector2_DW pt, Vector2_DW lnSt, Vector2_DW lnEnd, bool isSegment)
        {
            //设点为Q,线段为P1P2 ,判断点Q在该线段上的依据是:( Q - P1 ) × ( P2 - P1 ) = 0 且 Q 在以 P1,P2为对角顶点的矩形内。前者保证Q点在直线P1P2上,后者是保证Q点不在线段P1P2的延长线或反向延长线上
            //My Method:设点为Q,线段为P1P2 ,判断点Q在该线段上的依据是:( Q - P1 ) × ( P2 - P1 ) = 0 且 Q 到p1p2的距离==0。前者保证Q点在直线P1P2上,后者是保证Q点不在线段P1P2的延长线或反向延长线上
            Vector2_DW vec1 = pt - lnSt;
            Vector2_DW vec2 = pt - lnEnd;

            if (IsZero(Vector2_DW.Cross(vec1, vec2)) == true)
            {
                if (IsZero(LinePointDistance(lnSt, lnEnd, pt, isSegment)))
                {
                    return(true);
                }
            }
            return(false);
        }
Example #15
0
        //判断两个矩形是否相交(注:当一个矩形包围另一个矩形时,也认为是相交)
        public static bool BoxXBox(Box2D bx1, Box2D bx2)
        {
            Box2D intersectBx = new Box2D();//如果两个矩形相交,其相交区域必为矩形

            intersectBx._min = Vector2_DW.Max(bx1._min, bx2._min);
            intersectBx._max = Vector2_DW.Min(bx1._max, bx2._max);
            if (intersectBx._min.X > intersectBx._max.X ||
                intersectBx._min.Y > intersectBx._max.Y)
            {
                return(false);
            }
            else
            {
                return(true);
            }
        }
Example #16
0
        //获取points的最小包围盒和最左端的点
        static public Box2D GetMinBox(Vector2_DW[] points, ref Vector2_DW leftMostPt)
        {
            Box2D  bxRet          = new Box2D();
            int    n              = points.Length;
            double minX           = 0;
            double minY           = 0;
            double maxX           = 0;
            double maxY           = 0;
            int    nLeftMostIndex = 0;

            for (int i = 0; i < n; i++)
            {
                if (0 == i)
                {
                    minX = maxX = points[i].X;
                    minY = maxY = points[i].Y;
                }
                else
                {
                    if (points[i].X < minX)
                    {
                        minX           = points[i].X;
                        nLeftMostIndex = i;
                    }
                    if (points[i].Y < minY)
                    {
                        minY = points[i].Y;
                    }
                    if (points[i].X > maxX)
                    {
                        maxX = points[i].X;
                    }
                    if (points[i].Y > minY)
                    {
                        maxY = points[i].Y;
                    }
                }
            }
            bxRet._min = new Vector2_DW(minX, minY);
            bxRet._max = new Vector2_DW(maxX, maxY);
            leftMostPt = new Vector2_DW(points[nLeftMostIndex].X, points[nLeftMostIndex].Y);
            return(bxRet);
        }
Example #17
0
        /// <summary>
        /// 判断直线段与矩形是否相交(注:当线段全部在矩形内,也认为相交)
        /// 1,线段端点是否在矩形内,在,true
        /// 2,线段包围框是否和矩形相交,否,false
        /// 3,矩形四个顶点是否在线段两侧,在true,不在,false
        /// </summary>
        /// <param name="lStScreen"></param>
        /// <param name="lEndScreen"></param>
        /// <param name="bx"></param>
        /// <returns></returns>
        public static bool LineSegmenXBox(Vector2_DW lStScreen, Vector2_DW lEndScreen, Box2D bx)
        {
            if (ToolsMath_DW.PtInBox(bx, lStScreen) &&
                ToolsMath_DW.PtInBox(bx, lEndScreen))
            {
                return(true);
            }

            Box2D bxLine = ToolsMath_DW.GetLineMinBox(lStScreen, lEndScreen);

            if (!ToolsMath_DW.BoxXBox(bx, bxLine))
            {
                return(false);
            }

            Vector2_DW vecLn        = lStScreen - lEndScreen;
            Vector2_DW vBxLeftUpper = bx._min - lEndScreen;
            Vector2_DW vBxRightTop  = (new Vector2_DW(bx._max.X, bx._min.Y)) - lEndScreen;
            Vector2_DW vBxRightBtm  = bx._max - lEndScreen;
            Vector2_DW vBxLeftBtm   = (new Vector2_DW(bx._min.X, bx._max.Y)) - lEndScreen;

            double f1 = Vector2_DW.Cross(vecLn, vBxLeftUpper);
            double f2 = Vector2_DW.Cross(vecLn, vBxRightTop);
            double f3 = Vector2_DW.Cross(vecLn, vBxRightBtm);
            double f4 = Vector2_DW.Cross(vecLn, vBxLeftBtm);

            if ((f1 >= 0 && f2 >= 0 && f3 >= 0 && f4 >= 0)
                ||
                (f1 <= 0 && f2 <= 0 && f3 <= 0 && f4 <= 0))
            {
                return(false);
            }
            else
            {
                return(true);
            }
        }
Example #18
0
 public Vector2_DW(Vector2_DW vecSrc)
 {
     _x = vecSrc.X;
     _y = vecSrc.Y;
 }
Example #19
0
        public static LineIntersectType LineXLine(Vector2_DW p0, Vector2_DW p1, Vector2_DW p2, Vector2_DW p3, ref Vector2_DW xpt)
        {
            /*
            **  Get the intersection of the line defined by p0 and p1 with the
            **  line defined by p2 and p3.  Sets xpt to the intersection point
            **  if return value is non-negative.
            **
            **  Returns:
            **       None = Lines are paralell or the points are coincide[eg:p0(0, 0), p1(2, 0),p2(1, 0), p3(4, 0)].
            **       OnBothExtend = Intersection is not on either segment.
            **       OnFirstLine = Intersection is on the 1st segment (p0-p1) but not the 2nd.
            **       OnSecondLine = Intersection is on the 2nd segment (p2-p3) but not the 1st.
            **       OnBothLine = Intersection is on both line segments.
            */
            double a1 = p1.Y - p0.Y;
            double b1 = p0.X - p1.X;
            double c1 = a1 * p0.X + b1 * p0.Y;

            double a2 = p3.Y - p2.Y;
            double b2 = p2.X - p3.X;
            double c2 = a2 * p2.X + b2 * p2.Y;

            double denominator = a1 * b2 - a2 * b1;

            if (IsZero(denominator))
            {
                //paralell
                return(LineIntersectType.None);
            }
            else
            {
                int on1 = 1;
                int on2 = 1;

                xpt.X = (b2 * c1 - b1 * c2) / denominator;
                xpt.Y = (a1 * c2 - a2 * c1) / denominator;
                Vector2_DW vecMin = Vector2_DW.Min(p0, p1);
                Vector2_DW vecMax = Vector2_DW.Max(p0, p1);
                on1 = (vecMin.X <= xpt.X && xpt.X <= vecMax.X &&
                       vecMin.Y <= xpt.Y && xpt.Y <= vecMax.Y) ? 1 : 0;
                vecMin = Vector2_DW.Min(p2, p3);
                vecMax = Vector2_DW.Max(p2, p3);
                on2    = (vecMin.X <= xpt.X && xpt.X <= vecMax.X &&
                          vecMin.Y <= xpt.Y && xpt.Y <= vecMax.Y) ? 1 : 0;
                int result = on1 + 2 * on2;
                if (0 == result)
                {
                    return(LineIntersectType.OnBothExtend);
                }
                else if (1 == result)
                {
                    return(LineIntersectType.OnFirstLine);
                }
                else if (2 == result)
                {
                    return(LineIntersectType.OnSecondLine);
                }
                else// 3==result
                {
                    return(LineIntersectType.OnBothLine);
                }
            }
        }
Example #20
0
 public static Vector2_DW operator *(Vector2_DW lhs, double d)
 {
     Vector2_DW result = new Vector2_DW();
     result.X = d * lhs.X;
     result.Y = d * lhs.Y;
     return result;
 }
Example #21
0
 //返回两个向量之间的夹角(角度制)(0-180)
 public static double Angle(Vector2_DW from, Vector2_DW to)
 {
     return Math.Acos(ToolsMath_DW.Clamp(Vector2_DW.Dot(from.Normalize(), to.Normalize()), -1f, 1f)) * 57.29578f;
 }
Example #22
0
 //计算由a,b,c三点组成的向量 abxac的叉积,注:此处只是返回标量(平行四边形面积)并非实际意义上的叉积
 public static double Cross(Vector2_DW ptA, Vector2_DW ptB, Vector2_DW ptC)
 {
     Vector2_DW ab = ptB - ptA;// new Vector2_DW(b.X - a.X, b.Y - a.Y);
     Vector2_DW ac = ptC - ptA;// new Vector2_DW(c.X - a.X, c.Y - a.Y);
     return (ab.X * ac.Y - ac.X * ab.Y);
 }
Example #23
0
        /// <summary>
        /// 判断直线段与矩形是否相交(注:当线段全部在矩形内,也认为相交)
        /// 1,线段端点是否在矩形内,在,true
        /// 2,线段包围框是否和矩形相交,否,false
        /// 3,矩形四个顶点是否在线段两侧,在true,不在,false
        /// </summary>
        /// <param name="lStScreen"></param>
        /// <param name="lEndScreen"></param>
        /// <param name="bx"></param>
        /// <returns></returns>
        public static bool LineSegmenXBox(Vector2_DW lStScreen, Vector2_DW lEndScreen, Box2D bx)
        {
            if (ToolsMath_DW.PtInBox(bx, lStScreen)
                && ToolsMath_DW.PtInBox(bx, lEndScreen))
            {
                return true;
            }

            Box2D bxLine = ToolsMath_DW.GetLineMinBox(lStScreen, lEndScreen);
            if (!ToolsMath_DW.BoxXBox(bx, bxLine))
            {
                return false;
            }

            Vector2_DW vecLn = lStScreen - lEndScreen;
            Vector2_DW vBxLeftUpper = bx._min - lEndScreen;
            Vector2_DW vBxRightTop = (new Vector2_DW(bx._max.X, bx._min.Y)) - lEndScreen;
            Vector2_DW vBxRightBtm = bx._max - lEndScreen;
            Vector2_DW vBxLeftBtm = (new Vector2_DW(bx._min.X, bx._max.Y)) - lEndScreen;

            double f1 = Vector2_DW.Cross(vecLn, vBxLeftUpper);
            double f2 = Vector2_DW.Cross(vecLn, vBxRightTop);
            double f3 = Vector2_DW.Cross(vecLn, vBxRightBtm);
            double f4 = Vector2_DW.Cross(vecLn, vBxLeftBtm);
            if ((f1 >= 0 && f2 >= 0 && f3 >= 0 && f4 >= 0)
                ||
                (f1 <= 0 && f2 <= 0 && f3 <= 0 && f4 <= 0))
            {
                return false;
            }
            else
            {
                return true;
            }
        }
Example #24
0
        /// <summary>
        /// ///计算pos到直线(lineSt, lineEnd)的最短距离
        /// </summary>
        /// <param name="pos"></param>
        /// <param name="lineSt"></param>
        /// <param name="lineEnd"></param>
        /// <param name="lineIsSegment">是否为线段</param>
        /// <returns></returns>
        public static double LinePointDistance(Vector2_DW lineSt, Vector2_DW lineEnd, Vector2_DW pos, bool lineIsSegment)
        {
            double disRet = 0;
            if (lineIsSegment == false)
            {
                disRet = Vector2_DW.Cross(lineSt, lineEnd, pos) / Vector2_DW.Distance(lineSt, lineEnd);
            }
            else
            {
                Vector2_DW ab = lineEnd - lineSt;
                Vector2_DW bc = pos - lineEnd;
                Vector2_DW ac = pos - lineSt;

                if (Vector2_DW.Dot(ab, bc) > 0)//pos在lineEnd外侧
                {
                    disRet = Vector2_DW.Distance(pos, lineEnd);
                }
                else if (Vector2_DW.Dot(ab, ac) > 0)//pos在lineEnd外侧
                {
                    disRet = Vector2_DW.Distance(pos, lineSt);
                }
                else//pos在lineSt与lineEnd之间
                {
                    disRet = Vector2_DW.Cross(lineSt, lineEnd, pos) / Vector2_DW.Distance(lineSt, lineEnd);
                }
            }
            return Math.Abs(disRet);
        }
Example #25
0
 /// <summary>
 /// 判断点pt是否在直线上
 /// </summary>
 /// <param name="pt"></param>
 /// <param name="lnSt"></param>
 /// <param name="lnEnd"></param>
 /// <param name="isSegment">是否为直线段</param>
 /// <returns></returns>
 public static bool IsPointOnLine(Vector2_DW pt, Vector2_DW lnSt, Vector2_DW lnEnd, bool isSegment)
 {
     //设点为Q,线段为P1P2 ,判断点Q在该线段上的依据是:( Q - P1 ) × ( P2 - P1 ) = 0 且 Q 在以 P1,P2为对角顶点的矩形内。前者保证Q点在直线P1P2上,后者是保证Q点不在线段P1P2的延长线或反向延长线上
     //My Method:设点为Q,线段为P1P2 ,判断点Q在该线段上的依据是:( Q - P1 ) × ( P2 - P1 ) = 0 且 Q 到p1p2的距离==0。前者保证Q点在直线P1P2上,后者是保证Q点不在线段P1P2的延长线或反向延长线上
     Vector2_DW vec1 = pt - lnSt;
     Vector2_DW vec2 = pt - lnEnd;
     if (IsZero(Vector2_DW.Cross(vec1, vec2)) == true)
     {
         if (IsZero(LinePointDistance(lnSt, lnEnd, pt, isSegment)))
         {
             return true;
         }
     }
     return false;
 }
Example #26
0
 //获取points的最小包围盒和最左端的点
 public static Box2D GetMinBox(Vector2_DW[] points, ref Vector2_DW leftMostPt)
 {
     Box2D bxRet = new Box2D();
     int n = points.Length;
     double minX = 0;
     double minY = 0;
     double maxX = 0;
     double maxY = 0;
     int nLeftMostIndex = 0;
     for (int i = 0; i < n; i++)
     {
         if (0 == i)
         {
             minX = maxX = points[i].X;
             minY = maxY = points[i].Y;
         }
         else
         {
             if (points[i].X < minX)
             {
                 minX = points[i].X;
                 nLeftMostIndex = i;
             }
             if (points[i].Y < minY)
             {
                 minY = points[i].Y;
             }
             if (points[i].X > maxX)
             {
                 maxX = points[i].X;
             }
             if (points[i].Y > minY)
             {
                 maxY = points[i].Y;
             }
         }
     }
     bxRet._min = new Vector2_DW(minX, minY);
     bxRet._max = new Vector2_DW(maxX, maxY);
     leftMostPt = new Vector2_DW(points[nLeftMostIndex].X, points[nLeftMostIndex].Y);
     return bxRet;
 }
Example #27
0
 //获取直线的最小包围盒(传入的点的坐标为屏幕坐标)
 public static Box2D GetLineMinBox(Vector2_DW screenPtSt, Vector2_DW screenPtEnd)
 {
     Box2D bxRet = new Box2D();
     bxRet._min = Vector2_DW.Min(screenPtSt, screenPtEnd);
     bxRet._max = Vector2_DW.Max(screenPtSt, screenPtEnd);
     return bxRet;
 }
Example #28
0
 public Vector2_DW Scale(Vector2_DW size)
 {
     Vector2_DW ptRet = new Vector2_DW();
     this.X *= size.X;
     this.Y *= size.Y;
     return ptRet;
 }
Example #29
0
        public Vector2_DW Rotate(Vector2_DW ptBase, double angleDegree)
        {
            Vector2_DW ptRet = new Vector2_DW();
            Vector2_DW vec = this - ptBase;
            double angleRadium = ToolsMath_DW.Angle2Radium(angleDegree);
            double xOffset = (vec.X * Math.Cos(angleRadium) - vec.Y * Math.Sin(angleRadium));
            double yOffset = (vec.X * Math.Sin(angleRadium) + vec.Y * Math.Cos(angleRadium));

            ptRet = ptBase + new Vector2_DW(xOffset, yOffset);
            return ptRet;
        }
Example #30
0
 public Vector2_DW Move(Vector2_DW basePt, Vector2_DW desPt)
 {
     Vector2_DW ptRet = new Vector2_DW();
     Vector2_DW vecOffset = desPt - basePt;
     ptRet = this + vecOffset;
     return ptRet;
 }
Example #31
0
 static public double Dot(Vector2_DW lhs, Vector2_DW rhs)
 {
     return(lhs.X * rhs.X + lhs.Y * rhs.Y);
 }
        /// <summary>
        ///     根据导线点计算巷道左右帮的点
        ///     前后两个导线点坐标一样的情况未处理,传入的导线点数据需要保证不重复.
        /// </summary>
        /// <params name="wirePts">导线点实体</params>
        /// <params name="verticesLeftBtmRet">out,根据导线点计算出的巷道左帮所有点</params>
        /// <params name="verticesRightBtmRet">out,根据导线点计算出的巷道右帮所有点</params>
        /// <returns></returns>
        public bool calc_left_and_right_vertics(WirePoint[] wirePts, ref Vector3_DW[] verticesLeftBtmRet,
            ref Vector3_DW[] verticesRightBtmRet)
        {
            if (wirePts == null)
            {
                return false;
            }

            int nTraversePtCnt = wirePts.Length;
            if (nTraversePtCnt < 1)
            {
                return false;
            }

            #region 仅含两个导线点

            if (nTraversePtCnt == 2)
            {
                bool bRet = calc_left_and_right_vertics_with2_traver_points(wirePts, ref verticesLeftBtmRet,
                    ref verticesRightBtmRet);
                if (bRet == false)
                {
                    return false;
                }
            }
            #endregion
            #region 大于等于三个点

            else
            {
                var lstLeftBtmVertices = new List<Vector3_DW>();
                var lstRightBtmVertices = new List<Vector3_DW>();

                #region For loop

                for (int i = 0; i < nTraversePtCnt - 2; i++)
                {
                    var lwDatasPreTmp = new[]
                    {
                        wirePts[i],
                        wirePts[i + 1]
                    };

                    var lwDatasNextTmp = new[]
                    {
                        wirePts[i + 1],
                        wirePts[i + 2]
                    };

                    Vector3_DW[] verticesLeftPreTmp = null;
                    Vector3_DW[] verticesRightPreTmp = null;
                    if (false ==
                        calc_left_and_right_vertics_with2_traver_points(lwDatasPreTmp, ref verticesLeftPreTmp,
                            ref verticesRightPreTmp))
                    {
                        return false;
                    }
                    Vector3_DW[] verticesLeftNextTmp = null;
                    Vector3_DW[] verticesRightNextTmp = null;
                    if (false ==
                        calc_left_and_right_vertics_with2_traver_points(lwDatasNextTmp, ref verticesLeftNextTmp,
                            ref verticesRightNextTmp))
                    {
                        return false;
                    }
                    var vertexMid2D = new Vector2_DW();
                    var vertexLeftMid = new Vector3_DW();
                    var vertexRightMid = new Vector3_DW();
                    //左邦中间的点
                    LineIntersectType lit =
                        ToolsMath_DW.LineXLine(new Vector2_DW(verticesLeftPreTmp[0].X, verticesLeftPreTmp[0].Y),
                            new Vector2_DW(verticesLeftPreTmp[1].X, verticesLeftPreTmp[1].Y),
                            new Vector2_DW(verticesLeftNextTmp[0].X, verticesLeftNextTmp[0].Y),
                            new Vector2_DW(verticesLeftNextTmp[1].X, verticesLeftNextTmp[1].Y), ref vertexMid2D);
                    if (lit == LineIntersectType.None) //有重复点,可能是这种情况eg:p0(0, 0), p1(2, 0),p2(1, 0), p3(4, 0)
                    {
                        vertexLeftMid.X = verticesLeftPreTmp[1].X;
                        vertexLeftMid.Y = verticesLeftPreTmp[1].Y;
                        vertexLeftMid.Z = lwDatasPreTmp[1].coordinate_z;
                    }
                    else
                    {
                        vertexLeftMid.X = vertexMid2D.X;
                        vertexLeftMid.Y = vertexMid2D.Y;
                        vertexLeftMid.Z = lwDatasPreTmp[1].coordinate_z;
                    }
                    //右邦中间的点
                    lit = ToolsMath_DW.LineXLine(new Vector2_DW(verticesRightPreTmp[0].X, verticesRightPreTmp[0].Y),
                        new Vector2_DW(verticesRightPreTmp[1].X, verticesRightPreTmp[1].Y),
                        new Vector2_DW(verticesRightNextTmp[0].X, verticesRightNextTmp[0].Y),
                        new Vector2_DW(verticesRightNextTmp[1].X, verticesRightNextTmp[1].Y), ref vertexMid2D);
                    if (lit == LineIntersectType.None) //有重复点,可能是这种情况eg:p0(0, 0), p1(2, 0),p2(1, 0), p3(4, 0)
                    {
                        vertexRightMid.X = verticesRightPreTmp[1].X;
                        vertexRightMid.Y = verticesRightPreTmp[1].Y;
                        vertexRightMid.Z = lwDatasPreTmp[1].coordinate_z;
                    }
                    else
                    {
                        vertexRightMid.X = vertexMid2D.X;
                        vertexRightMid.Y = vertexMid2D.Y;
                        vertexRightMid.Z = lwDatasPreTmp[1].coordinate_z;
                    }
                    //保存计算出来的点
                    //第一个顶点
                    if (i == 0)
                    {
                        lstLeftBtmVertices.Add(verticesLeftPreTmp[0]);
                        lstRightBtmVertices.Add(verticesRightPreTmp[0]);
                    }
                    //中间的顶点
                    lstLeftBtmVertices.Add(vertexLeftMid);
                    lstRightBtmVertices.Add(vertexRightMid);
                    //最后一个顶点
                    if (i == nTraversePtCnt - 3)
                    {
                        lstLeftBtmVertices.Add(verticesLeftNextTmp[1]);
                        lstRightBtmVertices.Add(verticesRightNextTmp[1]);
                    }
                } //end for

                #endregion

                verticesLeftBtmRet = lstLeftBtmVertices.ToArray();
                verticesRightBtmRet = lstRightBtmVertices.ToArray();
            }

            #endregion

            return true;
        }
Example #33
0
 //计算abxac的叉积,注:此处只是返回标量(平行四边形面积)并非实际意义上的叉积
 static public double Cross(Vector2_DW vecL, Vector2_DW vecR)
 {
     return(vecL.X * vecR.Y - vecR.X * vecL.Y);
 }
Example #34
0
 public static Vector2_DW Min(Vector2_DW lhs, Vector2_DW rhs)
 {
     double x = Math.Min(lhs.X, rhs.X);
     double y = Math.Min(lhs.Y, rhs.Y);
     return new Vector2_DW(x, y);
 }
Example #35
0
 public static Vector2_DW operator -(Vector2_DW rhs)
 {
     Vector2_DW result = new Vector2_DW();
     result.X = -rhs.X;
     result.Y = -rhs.Y;
     return result;
 }
Example #36
0
 public static double Dot(Vector2_DW lhs, Vector2_DW rhs)
 {
     return (lhs.X * rhs.X + lhs.Y * rhs.Y);
 }
Example #37
0
 public static Vector2_DW operator *(double d, Vector2_DW rhs)
 {
     Vector2_DW result = new Vector2_DW();
     result.X = d * rhs.X;
     result.Y = d * rhs.Y;
     return result;
 }
Example #38
0
 //返回a,b两点之间的距离
 public static double Distance(Vector2_DW a, Vector2_DW b)
 {
     Vector2_DW vec = b - a;
     return vec.Magnitude();
 }
Example #39
0
 public Vector2_DW(Vector2_DW vecSrc)
 {
     _x = vecSrc.X;
     _y = vecSrc.Y;
 }
Example #40
0
 //计算abxac的叉积,注:此处只是返回标量(平行四边形面积)并非实际意义上的叉积
 public static double Cross(Vector2_DW vecL, Vector2_DW vecR)
 {
     return (vecL.X * vecR.Y - vecR.X * vecL.Y);
 }
Example #41
0
 //判断某一点是否在包围盒内
 public static bool PtInBox(Box2D bx, Vector2_DW posScreen)
 {
     if (posScreen.X > bx._min.X
         && posScreen.X < bx._max.X
         && posScreen.Y > bx._min.Y
         && posScreen.Y < bx._max.Y)
     {
         return true;
     }
     else
     {
         return false;
     }
 }
Example #42
0
        //返回a,b两点之间的距离
        static public double Distance(Vector2_DW a, Vector2_DW b)
        {
            Vector2_DW vec = b - a;

            return(vec.Magnitude());
        }
Example #43
0
        public static LineIntersectType LineXLine(Vector2_DW p0, Vector2_DW p1, Vector2_DW p2, Vector2_DW p3, ref Vector2_DW xpt)
        {
            /*
            **  Get the intersection of the line defined by p0 and p1 with the
            **  line defined by p2 and p3.  Sets xpt to the intersection point
            **  if return value is non-negative.
            **
            **  Returns:
            **       None = Lines are paralell or the points are coincide[eg:p0(0, 0), p1(2, 0),p2(1, 0), p3(4, 0)].
            **       OnBothExtend = Intersection is not on either segment.
            **       OnFirstLine = Intersection is on the 1st segment (p0-p1) but not the 2nd.
            **       OnSecondLine = Intersection is on the 2nd segment (p2-p3) but not the 1st.
            **       OnBothLine = Intersection is on both line segments.
            */
            double a1 = p1.Y - p0.Y;
            double b1 = p0.X - p1.X;
            double c1 = a1 * p0.X + b1 * p0.Y;

            double a2 = p3.Y - p2.Y;
            double b2 = p2.X - p3.X;
            double c2 = a2 * p2.X + b2 * p2.Y;

            double denominator = a1 * b2 - a2 * b1;
            if (IsZero(denominator))
            {
                //paralell
                return LineIntersectType.None;
            }
            else
            {
                int on1 = 1;
                int on2 = 1;

                xpt.X = (b2 * c1 - b1 * c2) / denominator;
                xpt.Y = (a1 * c2 - a2 * c1) / denominator;
                Vector2_DW vecMin = Vector2_DW.Min(p0, p1);
                Vector2_DW vecMax = Vector2_DW.Max(p0, p1);
                on1 = (vecMin.X <= xpt.X && xpt.X <= vecMax.X &&
                    vecMin.Y <= xpt.Y && xpt.Y <= vecMax.Y) ? 1 : 0;
                vecMin = Vector2_DW.Min(p2, p3);
                vecMax = Vector2_DW.Max(p2, p3);
                on2 = (vecMin.X <= xpt.X && xpt.X <= vecMax.X &&
                    vecMin.Y <= xpt.Y && xpt.Y <= vecMax.Y) ? 1 : 0;
                int result = on1 + 2 * on2;
                if (0 == result)
                {
                    return LineIntersectType.OnBothExtend;
                }
                else if (1 == result)
                {
                    return LineIntersectType.OnFirstLine;
                }
                else if (2 == result)
                {
                    return LineIntersectType.OnSecondLine;
                }
                else// 3==result
                {
                    return LineIntersectType.OnBothLine;
                }
            }
        }
Example #44
0
 //返回两个向量之间的夹角(角度制)(0-180)
 static public double Angle(Vector2_DW from, Vector2_DW to)
 {
     return(Math.Acos(ToolsMath_DW.Clamp(Vector2_DW.Dot(from.Normalize(), to.Normalize()), -1f, 1f)) * 57.29578f);
 }
        /// <summary>
        ///     计算仅含两个导线点的巷道的左右邦点
        /// </summary>
        /// <params name="wirePts"></params>
        /// <params name="verticesLeftRet"></params>
        /// <params name="verticesRightRet"></params>
        /// <returns></returns>
        private bool calc_left_and_right_vertics_with2_traver_points(WirePoint[] wirePts,
            ref Vector3_DW[] verticesLeftRet, ref Vector3_DW[] verticesRightRet)
        {
            if (wirePts == null)
            {
                return false;
            }

            int nTraversePtCnt = wirePts.Length;
            if (nTraversePtCnt != 2)
            {
                return false;
            }

            //仅含两个导线点
            if (nTraversePtCnt == 2)
            {
                var ptPre = new Vector2_DW(wirePts[0].coordinate_x, wirePts[0].coordinate_y);
                var ptNext = new Vector2_DW(wirePts[1].coordinate_x, wirePts[1].coordinate_y);

                Vector2_DW vecForwardDir = (ptNext - ptPre).Normalize();
                /*根据法线方向判断巷道左右邦.
                 * 若垂直向量vecPerpendicular与vecForwardDir的叉积所得向量与Y轴夹角小于90度(二者点积大于0),,则认为该垂直向量为左帮方向
                 * x1*x2 + y1*y2 = 0//垂直
                 * x1*y2 - x2*y1 = 0//平行
                 *
                 *点积 a●b=|a|*|b|*cos(w)=x1*x2+y1*y2=0
                 *叉积 aXb=|a|*|b|*sin(w)=(x1*z2-z1*y2)x^+(z1*x2-z1*y2)y^+(x1*y2-y1*x2)z^(右手螺旋定则)=0 -->二维的表示平行四边形的面积
                 *混合积 (aXb)●c = |aXb|*|c|*cos(aXb,c) -->平行六面体的体积
                 */
                var vecPerpendicularLeft = new Vector2_DW(vecForwardDir.Y, -vecForwardDir.X);
                Vector2_DW vecPerpendicularRight = -vecPerpendicularLeft;
                Vector3_DW vecNormal = Vector3_DW.Cross(new Vector3_DW(vecForwardDir.X, vecForwardDir.Y, 0),
                    new Vector3_DW(vecPerpendicularLeft.X, vecPerpendicularLeft.Y, 0));
                if (vecNormal.Z < 0)
                {
                    Vector2_DW vecSwap = vecPerpendicularLeft;
                    vecPerpendicularLeft = vecPerpendicularRight;
                    vecPerpendicularRight = vecSwap;
                }

                var leftVertices = new List<Vector3_DW>();
                var rightVertices = new List<Vector3_DW>();

                Vector2_DW ptLeftPre = ptPre + vecPerpendicularLeft * wirePts[0].left_distance;
                Vector2_DW ptLeftNext = ptNext + vecPerpendicularLeft * wirePts[1].left_distance;
                Vector2_DW ptRightPre = ptPre + vecPerpendicularRight * wirePts[0].right_distance;
                Vector2_DW ptRightNext = ptNext + vecPerpendicularRight * wirePts[1].right_distance;

                leftVertices.Add(new Vector3_DW(ptLeftPre.X, ptLeftPre.Y, wirePts[0].coordinate_z));
                leftVertices.Add(new Vector3_DW(ptLeftNext.X, ptLeftNext.Y, wirePts[1].coordinate_z));
                rightVertices.Add(new Vector3_DW(ptRightPre.X, ptRightPre.Y, wirePts[0].coordinate_z));
                rightVertices.Add(new Vector3_DW(ptRightNext.X, ptRightNext.Y, wirePts[1].coordinate_z));

                verticesLeftRet = leftVertices.ToArray();
                verticesRightRet = rightVertices.ToArray();
            }
            return true;
        }
Example #46
0
 public Vector2_DW Mirror(Vector2_DW lineSt, Vector2_DW lineEnd)
 {
     Vector2_DW ptRet = new Vector2_DW();
     Vector2_DW vecPer = (lineSt - lineEnd);
     Vector2_DW vec = new Vector2_DW(-vecPer.Y, vecPer.X);
     Vector2_DW ptTmp = new Vector2_DW(this + vec);
     Vector2_DW ptIntersect = new Vector2_DW();
     if (ToolsMath_DW.LineXLine(this, ptTmp, lineSt, lineEnd, ref ptIntersect) != LineIntersectType.None)
     {
         ptRet = ptIntersect + ptIntersect - this;
     }
     return ptRet;
 }