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