コード例 #1
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));
        }
コード例 #2
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);
        }
コード例 #3
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);
            }
        }