/// <summary> /// 获取线段与多边形的所有交点,并按从近到远排序。,float3 z记录与多边形相交的边。 /// </summary> /// <param name="line"></param> /// <param name="paths"></param> public void GetAllIntersectPoint(LineSegment2D line, ref List <Double3> paths) { List <Double3> listpath = new List <Double3>(); Double2 point = Double2.zero; Double2 point1 = Double2.zero; for (int i = 0; i < this.pointArr.Length; i++) { LineSegment2D ls = GetEdge(i); if (line.GetIntersectPoint(ls, ref point, ref point1) == true) { if (point1 == point) // 肯定是交于端点,需特殊处理 { if (point1 == ls.endPoint) { int id = (i + 1) % this.pointArr.Length; listpath.Add(new Double3(point1.x, point1.y, id)); } else { listpath.Add(new Double3(point1.x, point1.y, i)); } } else { if (point1 == ls.endPoint) { int id = (i + 1) % this.pointArr.Length; listpath.Add(new Double3(point1.x, point1.y, id)); } else { listpath.Add(new Double3(point1.x, point1.y, i)); } if (point == ls.endPoint) { int id = (i + 1) % this.pointArr.Length; listpath.Add(new Double3(point.x, point.y, id)); } else { listpath.Add(new Double3(point.x, point.y, i)); } } } } // 从近到远排好队。 if (listpath.Count > 1) { listpath.Sort((x, y) => MathUtil.GetCompareDis(new Double2(x.x, x.y), line.startPoint).CompareTo(MathUtil.GetCompareDis(new Double2(y.x, y.y), line.startPoint))); } paths = listpath; }
/// <summary> /// 获取挡格附近出生点 /// </summary> /// <param name="line"></param> /// <param name="offset"></param> /// <param name="bornPoint"></param> /// <returns></returns> public override bool GetBornPoint(LineSegment2D line, double offset, ref Double2 bornPoint) { Double2 pos1 = Double2.zero; for (int i = 0; i < GetEdgeNum(); i++) { if (line.GetIntersectPoint(GetEdge(i), ref bornPoint, ref pos1) == true) { bornPoint = line.normalizedDir * ((bornPoint - line.startPoint).magnitude + offset) + line.startPoint; return(true); } } return(false); }
/// <summary> /// 与线段的关系 /// </summary> /// <param name="line"></param> /// <returns></returns> public override LineRelation CheckLineRelation(LineSegment2D line) { Double2 pos = Double2.zero; Double2 pos1 = Double2.zero; for (int i = 0; i < GetEdgeNum(); i++) { if (line.GetIntersectPoint(GetEdge(i), ref pos, ref pos1) == true) { return(LineRelation.Intersect); } } return(LineRelation.Detach); }
/// <summary> /// 获取交点 /// </summary> /// <param name="line"></param> /// <param name="intersectPoint"></param> /// <returns></returns> public bool GetIntersectPoint(LineSegment2D line, ref Double2 intersectStartPoint, ref Double2 intersectEndPoint) { return(line.GetIntersectPoint(this, ref intersectStartPoint)); }
/// <summary> /// 最短射线包围盒路径 /// </summary> /// <param name="line">线段</param> /// <param name="offset">偏移值</param> /// <param name="rbi">包围盒信息</param> /// <returns>true,表示线段与aabb有相交,并返回最短包围路径</returns> public override RBIResultType RayboundingNearestPath(LineSegment2D line, double offset, ref RayboundingInfo rbi) { if (rbi == null) { rbi = new RayboundingInfo(); } int index = 0; Double3[] lineArray = new Double3[2]; Double2 intersectionPoint = Double2.zero; Double2 pos1 = Double2.zero; if (line.GetIntersectPoint(GetEdge(0), ref intersectionPoint, ref pos1) == true) { lineArray[index] = new Double3(intersectionPoint.x, intersectionPoint.y, 1); index++; } if (line.GetIntersectPoint(GetEdge(2), ref intersectionPoint, ref pos1) == true) { lineArray[index] = new Double3(intersectionPoint.x, intersectionPoint.y, 3); index++; } if (index < 2) { if (line.GetIntersectPoint(GetEdge(3), ref intersectionPoint, ref pos1) == true) { lineArray[index] = new Double3(intersectionPoint.x, intersectionPoint.y, 4); index++; } } if (index < 2) { if (line.GetIntersectPoint(GetEdge(1), ref intersectionPoint, ref pos1) == true) { lineArray[index] = new Double3(intersectionPoint.x, intersectionPoint.y, 2); index++; } } if (index == 2) { double v1 = (new Double2(lineArray[0].x, lineArray[0].y) - line.startPoint).sqrMagnitude; double v2 = (new Double2(lineArray[1].x, lineArray[1].y) - line.startPoint).sqrMagnitude; Double2 s; Double2 e; if (v1 < v2) { s = new Double2(lineArray[0].x, lineArray[0].y); e = new Double2(lineArray[1].x, lineArray[1].y); RayboundingNearestPath(new Double3(s.x, s.y, lineArray[0].z), new Double3(e.x, e.y, lineArray[1].z), offset, ref rbi.listpath); } else { e = new Double2(lineArray[0].x, lineArray[0].y); s = new Double2(lineArray[1].x, lineArray[1].y); RayboundingNearestPath(new Double3(s.x, s.y, lineArray[1].z), new Double3(e.x, e.y, lineArray[0].z), offset, ref rbi.listpath); } if (rbi.listpath != null && rbi.listpath.Count > 0) { rbi.CalcHelpData(line, offset, s, e); return(RBIResultType.Succ); } return(RBIResultType.Fail); } else { return(RBIResultType.Fail); } }
/// <summary> /// 最短射线包围盒路径 /// </summary> /// <param name="line">线段</param> /// <param name="offset">偏移值</param> /// <param name="rbi">包围盒信息</param> /// <returns>true,表示线段与aabb有相交,并返回最短包围路径</returns> public override RBIResultType RayboundingNearestPath(LineSegment2D line, double offset, ref RayboundingInfo rbi) { if (rbi == null) { rbi = new RayboundingInfo(); } List <Double3> lineArray = new List <Double3>(); Double2 intersectionPoint = Double2.zero; Double2 pos1 = Double2.zero; for (int i = 0; i < this.pointArr.Length; i++) { if (line.GetIntersectPoint(GetEdge(i), ref intersectionPoint, ref pos1) == true) { lineArray.Add(new Double3(intersectionPoint.x, intersectionPoint.y, i)); } } int count = lineArray.Count; if (count == 0) { return(RBIResultType.Fail); } else if (count % 2 == 1) { lineArray.Sort((x, y) => MathUtil.GetCompareDis(new Double2(x.x, x.y), line.startPoint).CompareTo(MathUtil.GetCompareDis(new Double2(y.x, y.y), line.startPoint))); if (CheckIn(line.startPoint) == true) { rbi.SetNear(line, offset, new Double2(lineArray[0].x, lineArray[0].y)); return(RBIResultType.UnCrossstartPointIn); } else { rbi.SetNear(line, offset, new Double2(lineArray[count - 1].x, lineArray[count - 1].y)); return(RBIResultType.UnCrossendPointIn); } } else { // 先按距离进行排序。 lineArray.Sort((x, y) => MathUtil.GetCompareDis(new Double2(x.x, x.y), line.startPoint).CompareTo(MathUtil.GetCompareDis(new Double2(y.x, y.y), line.startPoint))); // bool isCross = true; bool isPathDir = CheckPathDir(lineArray[0], lineArray[lineArray.Count - 1], ref isCross); if (isCross == false) { rbi.SetNear(line, offset, new Double2(lineArray[0].x, lineArray[0].y)); return(RBIResultType.UnCross); } List <Double2> temppaths = new List <Double2>(); RayboundingNearestPath(lineArray[0], lineArray[lineArray.Count - 1], offset, isPathDir, ref temppaths); if (rbi.listpath == null) { rbi.listpath = temppaths; } else { rbi.listpath.AddRange(temppaths); } // 排斥需要扣除的点。 for (int i = 1; i < lineArray.Count - 1; i += 2) { if (CheckisSubChild((int)lineArray[0].z, (int)lineArray[lineArray.Count - 1].z, isPathDir, (int)lineArray[i].z, (int)lineArray[i + 1].z) == false) { continue; } List <Double2> listTemp = new List <Double2>(); RayboundingNearestPath(lineArray[i], lineArray[i + 1], offset, isPathDir, ref listTemp); if (listTemp.Count > 0) { foreach (Double2 pos in listTemp) { rbi.listpath.Remove(pos); } } } // if (rbi.listpath != null && rbi.listpath.Count > 0) { rbi.CalcHelpData(line, offset, new Double2(lineArray[0].x, lineArray[0].y), new Double2(lineArray[lineArray.Count - 1].x, lineArray[lineArray.Count - 1].y)); return(RBIResultType.Succ); } return(RBIResultType.Fail); } }