public LineSegmentCircleIntersect(LineSegment segment, Vector3 circleCenter, float circleRadius) { Vector3 a = segment.A; Vector3 b = segment.B; Vector3 c = circleCenter; // Compute a normal perpendicular to the line and pointing to the point Vector3 up = Vector3.Cross(segment.A - circleCenter, segment.A - segment.B); // This points up from the line Vector3 normal = Vector3.Cross(up, segment.A - segment.B); float distanceToLine = 0.0f; if (normal.Length > 0.0f) { distanceToLine = Math.Abs(new Plane(normal, segment.A).Distance(circleCenter)); } if (distanceToLine >= circleRadius) { intersectType = IntersectType.None; return; } if (distanceToLine == float.NaN) { } float along = (float)Math.Sqrt(Math.Pow(circleRadius, 2) - Math.Pow(distanceToLine, 2)); Plane plane = new Plane(b - a, a); float toA = 0.0f; float toB = plane.Distance(b); float toC = plane.Distance(c); float toP1 = toC - along; float toP2 = toC + along; if (toP2 < toA || toP1 > toB) { intersectType = IntersectType.None; return; } if (toP1 > toA) { beginNoIntersect = new LineSegment(a, a + toA * plane.Normal); } if (toP2 < toB) { endNoIntersect = new LineSegment(a + toP2 * plane.Normal, a + toB * plane.Normal); } toP1 = Math.Min(Math.Max(toP1, toA), toB); toP2 = Math.Min(Math.Max(toP2, toA), toB); intersectType = IntersectType.Segment; intersectSegment = new LineSegment(a + plane.Normal * toP1, a + plane.Normal * toP2); }
/// <summary> /// Subtract another line segment from this one. /// It's assumed that the other segment lies on the same line as this one. /// </summary> /// <param name="other"></param> public List<LineSegment> Subtract(LineSegment other) { //Vector3 n = b - a; //n.Normalize(); Plane plane = new Plane(b - a, a); float toB = plane.Distance(b); float toOtherA = plane.Distance(other.a); float toOtherB = plane.Distance(other.b); if (toOtherA > toOtherB) { float temp = toOtherA; toOtherA = toOtherB; toOtherB = temp; } else { } List<LineSegment> remainingSegments = new List<LineSegment>(); // Check for no overlap if (toOtherA >= toB || toOtherB <= 0.0f) { remainingSegments.Add(new LineSegment(a, b)); return remainingSegments; } if (toOtherA > 0) { Vector3 p1 = a; remainingSegments.Add(new LineSegment(a, a + plane.Normal * toOtherA)); } if (toOtherB < toB) { remainingSegments.Add(new LineSegment(a + plane.Normal * toOtherB, b)); } return remainingSegments; }