/// <summary> /// 获取近的相交点 /// </summary> /// <param name="line"></param> /// <param name="intersectStart"></param> /// <returns></returns> public override bool GetNearIntersectPoint(LineSegment2D line, ref Double2 intersectStart) { double radis2 = this.radius * this.radius; Double2 projectoint = line.ProjectPoint(this.circleCenter); Double2 diff = this.circleCenter - projectoint; // 跟直线相交奥 double dis = diff.sqrMagnitude - radis2; if (dis < 0) { double dis1 = (this.circleCenter - line.startPoint).sqrMagnitude; double dis2 = (this.circleCenter - line.endPoint).sqrMagnitude; if (dis1 >= radis2 && dis2 <= radis2) { dis = System.Math.Sqrt(dis); intersectStart = projectoint - line.normalizedDir * dis; return(true); } else if (dis1 <= radis2 && dis2 >= radis2) { dis = System.Math.Sqrt(dis); intersectStart = projectoint + line.normalizedDir * dis; return(true); } } return(false); }
/// <summary> /// 计算超出线段范围 /// </summary> /// <param name="lineStart"></param> /// <param name="lineEnd"></param> /// <param name="listMidPoint"></param> /// <param name="nearestIndex"></param> /// <param name="farestIndex"></param> private static void CalcNearFarest(Double2 lineStart, Double2 lineEnd, List <Double2> listMidPoint, ref int nearestIndex, ref int farestIndex) { if (listMidPoint == null || listMidPoint.Count == 0) { return; } nearestIndex = -1; farestIndex = -1; double outStartdis = 0; double outEnddis = 0; LineSegment2D line = new LineSegment2D(lineStart, lineEnd); for (int i = 0; i < listMidPoint.Count; i++) { ProjectPointInLine pp = line.CheckProjectInLine(listMidPoint[i]); if (pp == ProjectPointInLine.In) { continue; } Double2 projectPoint = line.ProjectPoint(listMidPoint[i]); if (pp == ProjectPointInLine.OutStart) { double dis = (projectPoint - lineStart).sqrMagnitude; if (dis > outStartdis) { outStartdis = dis; nearestIndex = i; } } else if (pp == ProjectPointInLine.OutStart) { double dis = (projectPoint - lineEnd).sqrMagnitude; if (dis > outEnddis) { outEnddis = dis; farestIndex = i; } } } }
/// <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(); } Double2 diff = this.circleCenter - line.startPoint; if (diff == Double2.zero) { return(RBIResultType.Fail); } // Double2 projectoint = line.ProjectPoint(this.circleCenter); diff = this.circleCenter - projectoint; // 跟直线相交奥 double dis = diff.sqrMagnitude - this.radius * this.radius; if (dis >= 0) { return(RBIResultType.Fail); } dis = -dis; // 在同侧不行。 Double2 diff1 = line.startPoint - projectoint; Double2 diff2 = line.endPoint - projectoint; if (Double2.Dot(diff1, diff2) >= 0) { return(RBIResultType.Fail); } // if (diff1.sqrMagnitude < dis || diff2.sqrMagnitude < dis) { return(RBIResultType.Fail); } dis = System.Math.Sqrt(dis) + offset; Double2 p1 = projectoint - line.normalizedDir * dis; Double2 p2 = projectoint + line.normalizedDir * dis; double bigRadius = this.radius + offset; double angle = SignedAngleInCircle(p1 - this.circleCenter, p2 - this.circleCenter, bigRadius); int count = (int)(System.Math.Abs(angle / 0.25f)); double diffangle = angle / count; List <Double2> listpath = new List <Double2>(); Double2 startVector = (p1 - this.circleCenter).normalized * bigRadius; for (int i = 1; i <= count - 1; i++) { Double2 rorateVector = Double2.Rotate(startVector, -diffangle * i); listpath.Add(rorateVector + this.circleCenter); } rbi.listpath = listpath; if (rbi.listpath != null && rbi.listpath.Count > 0) { rbi.CalcHelpData(line, offset, p1, p2); return(RBIResultType.Succ); } return(RBIResultType.Fail); }