diff --git a/OpenNest.Core/Geometry/Arc.cs b/OpenNest.Core/Geometry/Arc.cs index d48792f..bbd2d3f 100644 --- a/OpenNest.Core/Geometry/Arc.cs +++ b/OpenNest.Core/Geometry/Arc.cs @@ -465,7 +465,7 @@ namespace OpenNest.Geometry public override bool Intersects(Arc arc) { List pts; - return Helper.Intersects(this, arc, out pts); + return Intersect.Intersects(this, arc, out pts); } /// @@ -476,7 +476,7 @@ namespace OpenNest.Geometry /// public override bool Intersects(Arc arc, out List pts) { - return Helper.Intersects(this, arc, out pts); ; + return Intersect.Intersects(this, arc, out pts); ; } /// @@ -487,7 +487,7 @@ namespace OpenNest.Geometry public override bool Intersects(Circle circle) { List pts; - return Helper.Intersects(this, circle, out pts); + return Intersect.Intersects(this, circle, out pts); } /// @@ -498,7 +498,7 @@ namespace OpenNest.Geometry /// public override bool Intersects(Circle circle, out List pts) { - return Helper.Intersects(this, circle, out pts); + return Intersect.Intersects(this, circle, out pts); } /// @@ -509,7 +509,7 @@ namespace OpenNest.Geometry public override bool Intersects(Line line) { List pts; - return Helper.Intersects(this, line, out pts); + return Intersect.Intersects(this, line, out pts); } /// @@ -520,7 +520,7 @@ namespace OpenNest.Geometry /// public override bool Intersects(Line line, out List pts) { - return Helper.Intersects(this, line, out pts); + return Intersect.Intersects(this, line, out pts); } /// @@ -531,7 +531,7 @@ namespace OpenNest.Geometry public override bool Intersects(Polygon polygon) { List pts; - return Helper.Intersects(this, polygon, out pts); + return Intersect.Intersects(this, polygon, out pts); } /// @@ -542,7 +542,7 @@ namespace OpenNest.Geometry /// public override bool Intersects(Polygon polygon, out List pts) { - return Helper.Intersects(this, polygon, out pts); + return Intersect.Intersects(this, polygon, out pts); } /// @@ -553,7 +553,7 @@ namespace OpenNest.Geometry public override bool Intersects(Shape shape) { List pts; - return Helper.Intersects(this, shape, out pts); + return Intersect.Intersects(this, shape, out pts); } /// @@ -564,7 +564,7 @@ namespace OpenNest.Geometry /// public override bool Intersects(Shape shape, out List pts) { - return Helper.Intersects(this, shape, out pts); + return Intersect.Intersects(this, shape, out pts); } /// diff --git a/OpenNest.Core/Geometry/Circle.cs b/OpenNest.Core/Geometry/Circle.cs index 859d51a..82a0b3e 100644 --- a/OpenNest.Core/Geometry/Circle.cs +++ b/OpenNest.Core/Geometry/Circle.cs @@ -320,7 +320,7 @@ namespace OpenNest.Geometry public override bool Intersects(Arc arc) { List pts; - return Helper.Intersects(arc, this, out pts); + return Intersect.Intersects(arc, this, out pts); } /// @@ -331,7 +331,7 @@ namespace OpenNest.Geometry /// public override bool Intersects(Arc arc, out List pts) { - return Helper.Intersects(arc, this, out pts); + return Intersect.Intersects(arc, this, out pts); } /// @@ -353,7 +353,7 @@ namespace OpenNest.Geometry /// public override bool Intersects(Circle circle, out List pts) { - return Helper.Intersects(this, circle, out pts); + return Intersect.Intersects(this, circle, out pts); } /// @@ -364,7 +364,7 @@ namespace OpenNest.Geometry public override bool Intersects(Line line) { List pts; - return Helper.Intersects(this, line, out pts); + return Intersect.Intersects(this, line, out pts); } /// @@ -375,7 +375,7 @@ namespace OpenNest.Geometry /// public override bool Intersects(Line line, out List pts) { - return Helper.Intersects(this, line, out pts); + return Intersect.Intersects(this, line, out pts); } /// @@ -386,7 +386,7 @@ namespace OpenNest.Geometry public override bool Intersects(Polygon polygon) { List pts; - return Helper.Intersects(this, polygon, out pts); + return Intersect.Intersects(this, polygon, out pts); } /// @@ -397,7 +397,7 @@ namespace OpenNest.Geometry /// public override bool Intersects(Polygon polygon, out List pts) { - return Helper.Intersects(this, polygon, out pts); + return Intersect.Intersects(this, polygon, out pts); } /// @@ -408,7 +408,7 @@ namespace OpenNest.Geometry public override bool Intersects(Shape shape) { List pts; - return Helper.Intersects(this, shape, out pts); + return Intersect.Intersects(this, shape, out pts); } /// @@ -419,7 +419,7 @@ namespace OpenNest.Geometry /// public override bool Intersects(Shape shape, out List pts) { - return Helper.Intersects(this, shape, out pts); + return Intersect.Intersects(this, shape, out pts); } /// diff --git a/OpenNest.Core/Geometry/Intersect.cs b/OpenNest.Core/Geometry/Intersect.cs new file mode 100644 index 0000000..8af27e1 --- /dev/null +++ b/OpenNest.Core/Geometry/Intersect.cs @@ -0,0 +1,373 @@ +using System.Collections.Generic; +using System.Linq; +using OpenNest.Math; + +namespace OpenNest.Geometry +{ + public static class Intersect + { + internal static bool Intersects(Arc arc1, Arc arc2, out List pts) + { + var c1 = new Circle(arc1.Center, arc1.Radius); + var c2 = new Circle(arc2.Center, arc2.Radius); + + if (!Intersects(c1, c2, out pts)) + { + pts = new List(); + return false; + } + + pts = pts.Where(pt => + Angle.IsBetweenRad(arc1.Center.AngleTo(pt), arc1.StartAngle, arc1.EndAngle, arc1.IsReversed) && + Angle.IsBetweenRad(arc2.Center.AngleTo(pt), arc2.StartAngle, arc2.EndAngle, arc2.IsReversed)) + .ToList(); + + return pts.Count > 0; + } + + internal static bool Intersects(Arc arc, Circle circle, out List pts) + { + var c1 = new Circle(arc.Center, arc.Radius); + + if (!Intersects(c1, circle, out pts)) + { + pts = new List(); + return false; + } + + pts = pts.Where(pt => Angle.IsBetweenRad( + arc.Center.AngleTo(pt), + arc.StartAngle, + arc.EndAngle, + arc.IsReversed)).ToList(); + + return pts.Count > 0; + } + + internal static bool Intersects(Arc arc, Line line, out List pts) + { + var c1 = new Circle(arc.Center, arc.Radius); + + if (!Intersects(c1, line, out pts)) + { + pts = new List(); + return false; + } + + pts = pts.Where(pt => Angle.IsBetweenRad( + arc.Center.AngleTo(pt), + arc.StartAngle, + arc.EndAngle, + arc.IsReversed)).ToList(); + + return pts.Count > 0; + } + + internal static bool Intersects(Arc arc, Shape shape, out List pts) + { + var pts2 = new List(); + + foreach (var geo in shape.Entities) + { + List pts3; + geo.Intersects(arc, out pts3); + pts2.AddRange(pts3); + } + + pts = pts2.Where(pt => Angle.IsBetweenRad( + arc.Center.AngleTo(pt), + arc.StartAngle, + arc.EndAngle, + arc.IsReversed)).ToList(); + + return pts.Count > 0; + } + + internal static bool Intersects(Arc arc, Polygon polygon, out List pts) + { + var pts2 = new List(); + var lines = polygon.ToLines(); + + foreach (var line in lines) + { + List pts3; + Intersects(arc, line, out pts3); + pts2.AddRange(pts3); + } + + pts = pts2.Where(pt => Angle.IsBetweenRad( + arc.Center.AngleTo(pt), + arc.StartAngle, + arc.EndAngle, + arc.IsReversed)).ToList(); + + return pts.Count > 0; + } + + internal static bool Intersects(Circle circle1, Circle circle2, out List pts) + { + var distance = circle1.Center.DistanceTo(circle2.Center); + + // check if circles are too far apart + if (distance > circle1.Radius + circle2.Radius) + { + pts = new List(); + return false; + } + + // check if one circle contains the other + if (distance < System.Math.Abs(circle1.Radius - circle2.Radius)) + { + pts = new List(); + return false; + } + + var d = circle2.Center - circle1.Center; + var a = (circle1.Radius * circle1.Radius - circle2.Radius * circle2.Radius + distance * distance) / (2.0 * distance); + var h = System.Math.Sqrt(circle1.Radius * circle1.Radius - a * a); + + var pt = new Vector( + circle1.Center.X + (a * d.X) / distance, + circle1.Center.Y + (a * d.Y) / distance); + + var i1 = new Vector( + pt.X + (h * d.Y) / distance, + pt.Y - (h * d.X) / distance); + + var i2 = new Vector( + pt.X - (h * d.Y) / distance, + pt.Y + (h * d.X) / distance); + + pts = i1 != i2 ? new List { i1, i2 } : new List { i1 }; + + return true; + } + + internal static bool Intersects(Circle circle, Line line, out List pts) + { + var d1 = line.EndPoint - line.StartPoint; + var d2 = line.StartPoint - circle.Center; + + var a = d1.X * d1.X + d1.Y * d1.Y; + var b = (d1.X * d2.X + d1.Y * d2.Y) * 2; + var c = (d2.X * d2.X + d2.Y * d2.Y) - circle.Radius * circle.Radius; + + var det = b * b - 4 * a * c; + + if ((a <= Tolerance.Epsilon) || (det < 0)) + { + pts = new List(); + return false; + } + + double t; + pts = new List(); + + if (det.IsEqualTo(0)) + { + t = -b / (2 * a); + var pt1 = new Vector(line.StartPoint.X + t * d1.X, line.StartPoint.Y + t * d1.Y); + + if (line.BoundingBox.Contains(pt1)) + pts.Add(pt1); + + return true; + } + + t = (-b + System.Math.Sqrt(det)) / (2 * a); + var pt2 = new Vector(line.StartPoint.X + t * d1.X, line.StartPoint.Y + t * d1.Y); + + if (line.BoundingBox.Contains(pt2)) + pts.Add(pt2); + + t = (-b - System.Math.Sqrt(det)) / (2 * a); + var pt3 = new Vector(line.StartPoint.X + t * d1.X, line.StartPoint.Y + t * d1.Y); + + if (line.BoundingBox.Contains(pt3)) + pts.Add(pt3); + + return true; + } + + internal static bool Intersects(Circle circle, Shape shape, out List pts) + { + pts = new List(); + + foreach (var geo in shape.Entities) + { + List pts3; + geo.Intersects(circle, out pts3); + pts.AddRange(pts3); + } + + return pts.Count > 0; + } + + internal static bool Intersects(Circle circle, Polygon polygon, out List pts) + { + pts = new List(); + var lines = polygon.ToLines(); + + foreach (var line in lines) + { + List pts3; + Intersects(circle, line, out pts3); + pts.AddRange(pts3); + } + + return pts.Count > 0; + } + + internal static bool Intersects(Line line1, Line line2, out Vector pt) + { + var a1 = line1.EndPoint.Y - line1.StartPoint.Y; + var b1 = line1.StartPoint.X - line1.EndPoint.X; + var c1 = a1 * line1.StartPoint.X + b1 * line1.StartPoint.Y; + + var a2 = line2.EndPoint.Y - line2.StartPoint.Y; + var b2 = line2.StartPoint.X - line2.EndPoint.X; + var c2 = a2 * line2.StartPoint.X + b2 * line2.StartPoint.Y; + + var d = a1 * b2 - a2 * b1; + + if (d.IsEqualTo(0.0)) + { + pt = Vector.Zero; + return false; + } + + var x = (b2 * c1 - b1 * c2) / d; + var y = (a1 * c2 - a2 * c1) / d; + + pt = new Vector(x, y); + return line1.BoundingBox.Contains(pt) && line2.BoundingBox.Contains(pt); + } + + internal static bool Intersects(Line line, Shape shape, out List pts) + { + pts = new List(); + + foreach (var geo in shape.Entities) + { + List pts3; + geo.Intersects(line, out pts3); + pts.AddRange(pts3); + } + + return pts.Count > 0; + } + + internal static bool Intersects(Line line, Polygon polygon, out List pts) + { + pts = new List(); + var lines = polygon.ToLines(); + + foreach (var line2 in lines) + { + Vector pt; + + if (Intersects(line, line2, out pt)) + pts.Add(pt); + } + + return pts.Count > 0; + } + + internal static bool Intersects(Shape shape1, Shape shape2, out List pts) + { + pts = new List(); + + for (int i = 0; i < shape1.Entities.Count; i++) + { + var geo1 = shape1.Entities[i]; + + for (int j = 0; j < shape2.Entities.Count; j++) + { + List pts2; + bool success = false; + + var geo2 = shape2.Entities[j]; + + switch (geo2.Type) + { + case EntityType.Arc: + success = geo1.Intersects((Arc)geo2, out pts2); + break; + + case EntityType.Circle: + success = geo1.Intersects((Circle)geo2, out pts2); + break; + + case EntityType.Line: + success = geo1.Intersects((Line)geo2, out pts2); + break; + + case EntityType.Shape: + success = geo1.Intersects((Shape)geo2, out pts2); + break; + + case EntityType.Polygon: + success = geo1.Intersects((Polygon)geo2, out pts2); + break; + + default: + continue; + } + + if (success) + pts.AddRange(pts2); + } + } + + return pts.Count > 0; + } + + internal static bool Intersects(Shape shape, Polygon polygon, out List pts) + { + pts = new List(); + + var lines = polygon.ToLines(); + + for (int i = 0; i < shape.Entities.Count; i++) + { + var geo = shape.Entities[i]; + + for (int j = 0; j < lines.Count; j++) + { + var line = lines[j]; + + List pts2; + + if (geo.Intersects(line, out pts2)) + pts.AddRange(pts2); + } + } + + return pts.Count > 0; + } + + internal static bool Intersects(Polygon polygon1, Polygon polygon2, out List pts) + { + pts = new List(); + + var lines1 = polygon1.ToLines(); + var lines2 = polygon2.ToLines(); + + for (int i = 0; i < lines1.Count; i++) + { + var line1 = lines1[i]; + + for (int j = 0; j < lines2.Count; j++) + { + var line2 = lines2[j]; + Vector pt; + + if (Intersects(line1, line2, out pt)) + pts.Add(pt); + } + } + + return pts.Count > 0; + } + } +} diff --git a/OpenNest.Core/Geometry/Line.cs b/OpenNest.Core/Geometry/Line.cs index 0145f9e..d4c5cc2 100644 --- a/OpenNest.Core/Geometry/Line.cs +++ b/OpenNest.Core/Geometry/Line.cs @@ -456,7 +456,7 @@ namespace OpenNest.Geometry public override bool Intersects(Arc arc) { List pts; - return Helper.Intersects(arc, this, out pts); + return Intersect.Intersects(arc, this, out pts); } /// @@ -467,7 +467,7 @@ namespace OpenNest.Geometry /// public override bool Intersects(Arc arc, out List pts) { - return Helper.Intersects(arc, this, out pts); + return Intersect.Intersects(arc, this, out pts); } /// @@ -478,7 +478,7 @@ namespace OpenNest.Geometry public override bool Intersects(Circle circle) { List pts; - return Helper.Intersects(circle, this, out pts); + return Intersect.Intersects(circle, this, out pts); } /// @@ -489,7 +489,7 @@ namespace OpenNest.Geometry /// public override bool Intersects(Circle circle, out List pts) { - return Helper.Intersects(circle, this, out pts); + return Intersect.Intersects(circle, this, out pts); } /// @@ -512,7 +512,7 @@ namespace OpenNest.Geometry public override bool Intersects(Line line, out List pts) { Vector pt; - var success = Helper.Intersects(this, line, out pt); + var success = Intersect.Intersects(this, line, out pt); pts = new List(new[] { pt }); return success; } @@ -525,7 +525,7 @@ namespace OpenNest.Geometry public override bool Intersects(Polygon polygon) { List pts; - return Helper.Intersects(this, polygon, out pts); + return Intersect.Intersects(this, polygon, out pts); } /// @@ -536,7 +536,7 @@ namespace OpenNest.Geometry /// public override bool Intersects(Polygon polygon, out List pts) { - return Helper.Intersects(this, polygon, out pts); + return Intersect.Intersects(this, polygon, out pts); } /// @@ -547,7 +547,7 @@ namespace OpenNest.Geometry public override bool Intersects(Shape shape) { List pts; - return Helper.Intersects(this, shape, out pts); + return Intersect.Intersects(this, shape, out pts); } /// @@ -558,7 +558,7 @@ namespace OpenNest.Geometry /// public override bool Intersects(Shape shape, out List pts) { - return Helper.Intersects(this, shape, out pts); + return Intersect.Intersects(this, shape, out pts); } /// diff --git a/OpenNest.Core/Geometry/Polygon.cs b/OpenNest.Core/Geometry/Polygon.cs index e48bf24..2f09e65 100644 --- a/OpenNest.Core/Geometry/Polygon.cs +++ b/OpenNest.Core/Geometry/Polygon.cs @@ -364,7 +364,7 @@ namespace OpenNest.Geometry public override bool Intersects(Arc arc) { List pts; - return Helper.Intersects(arc, this, out pts); + return Intersect.Intersects(arc, this, out pts); } /// @@ -375,7 +375,7 @@ namespace OpenNest.Geometry /// public override bool Intersects(Arc arc, out List pts) { - return Helper.Intersects(arc, this, out pts); + return Intersect.Intersects(arc, this, out pts); } /// @@ -386,7 +386,7 @@ namespace OpenNest.Geometry public override bool Intersects(Circle circle) { List pts; - return Helper.Intersects(circle, this, out pts); + return Intersect.Intersects(circle, this, out pts); } /// @@ -397,7 +397,7 @@ namespace OpenNest.Geometry /// public override bool Intersects(Circle circle, out List pts) { - return Helper.Intersects(circle, this, out pts); + return Intersect.Intersects(circle, this, out pts); } /// @@ -408,7 +408,7 @@ namespace OpenNest.Geometry public override bool Intersects(Line line) { List pts; - return Helper.Intersects(line, this, out pts); + return Intersect.Intersects(line, this, out pts); } /// @@ -419,7 +419,7 @@ namespace OpenNest.Geometry /// public override bool Intersects(Line line, out List pts) { - return Helper.Intersects(line, this, out pts); + return Intersect.Intersects(line, this, out pts); } /// @@ -430,7 +430,7 @@ namespace OpenNest.Geometry public override bool Intersects(Polygon polygon) { List pts; - return Helper.Intersects(this, polygon, out pts); + return Intersect.Intersects(this, polygon, out pts); } /// @@ -441,7 +441,7 @@ namespace OpenNest.Geometry /// public override bool Intersects(Polygon polygon, out List pts) { - return Helper.Intersects(this, polygon, out pts); + return Intersect.Intersects(this, polygon, out pts); } /// @@ -452,7 +452,7 @@ namespace OpenNest.Geometry public override bool Intersects(Shape shape) { List pts; - return Helper.Intersects(shape, this, out pts); + return Intersect.Intersects(shape, this, out pts); } /// @@ -463,7 +463,7 @@ namespace OpenNest.Geometry /// public override bool Intersects(Shape shape, out List pts) { - return Helper.Intersects(shape, this, out pts); + return Intersect.Intersects(shape, this, out pts); } /// diff --git a/OpenNest.Core/Geometry/Shape.cs b/OpenNest.Core/Geometry/Shape.cs index 9f11945..03076d2 100644 --- a/OpenNest.Core/Geometry/Shape.cs +++ b/OpenNest.Core/Geometry/Shape.cs @@ -534,7 +534,7 @@ namespace OpenNest.Geometry { Vector intersection; - if (Helper.Intersects(offsetLine, lastOffsetLine, out intersection)) + if (Intersect.Intersects(offsetLine, lastOffsetLine, out intersection)) { offsetLine.StartPoint = intersection; lastOffsetLine.EndPoint = intersection; @@ -577,7 +577,7 @@ namespace OpenNest.Geometry public override bool Intersects(Arc arc) { List pts; - return Helper.Intersects(arc, this, out pts); + return Intersect.Intersects(arc, this, out pts); } /// @@ -588,7 +588,7 @@ namespace OpenNest.Geometry /// public override bool Intersects(Arc arc, out List pts) { - return Helper.Intersects(arc, this, out pts); + return Intersect.Intersects(arc, this, out pts); } /// @@ -599,7 +599,7 @@ namespace OpenNest.Geometry public override bool Intersects(Circle circle) { List pts; - return Helper.Intersects(circle, this, out pts); + return Intersect.Intersects(circle, this, out pts); } /// @@ -610,7 +610,7 @@ namespace OpenNest.Geometry /// public override bool Intersects(Circle circle, out List pts) { - return Helper.Intersects(circle, this, out pts); + return Intersect.Intersects(circle, this, out pts); } /// @@ -621,7 +621,7 @@ namespace OpenNest.Geometry public override bool Intersects(Line line) { List pts; - return Helper.Intersects(line, this, out pts); + return Intersect.Intersects(line, this, out pts); } /// @@ -632,7 +632,7 @@ namespace OpenNest.Geometry /// public override bool Intersects(Line line, out List pts) { - return Helper.Intersects(line, this, out pts); + return Intersect.Intersects(line, this, out pts); } /// @@ -643,7 +643,7 @@ namespace OpenNest.Geometry public override bool Intersects(Polygon polygon) { List pts; - return Helper.Intersects(this, polygon, out pts); + return Intersect.Intersects(this, polygon, out pts); } /// @@ -654,7 +654,7 @@ namespace OpenNest.Geometry /// public override bool Intersects(Polygon polygon, out List pts) { - return Helper.Intersects(this, polygon, out pts); + return Intersect.Intersects(this, polygon, out pts); } /// @@ -665,7 +665,7 @@ namespace OpenNest.Geometry public override bool Intersects(Shape shape) { List pts; - return Helper.Intersects(this, shape, out pts); + return Intersect.Intersects(this, shape, out pts); } /// @@ -676,7 +676,7 @@ namespace OpenNest.Geometry /// public override bool Intersects(Shape shape, out List pts) { - return Helper.Intersects(this, shape, out pts); + return Intersect.Intersects(this, shape, out pts); } /// diff --git a/OpenNest.Core/Helper.cs b/OpenNest.Core/Helper.cs index 1c0fd75..e9ba40e 100644 --- a/OpenNest.Core/Helper.cs +++ b/OpenNest.Core/Helper.cs @@ -11,370 +11,6 @@ namespace OpenNest { public static class Helper { - internal static bool Intersects(Arc arc1, Arc arc2, out List pts) - { - var c1 = new Circle(arc1.Center, arc1.Radius); - var c2 = new Circle(arc2.Center, arc2.Radius); - - if (!Intersects(c1, c2, out pts)) - { - pts = new List(); - return false; - } - - pts = pts.Where(pt => - Angle.IsBetweenRad(arc1.Center.AngleTo(pt), arc1.StartAngle, arc1.EndAngle, arc1.IsReversed) && - Angle.IsBetweenRad(arc2.Center.AngleTo(pt), arc2.StartAngle, arc2.EndAngle, arc2.IsReversed)) - .ToList(); - - return pts.Count > 0; - } - - internal static bool Intersects(Arc arc, Circle circle, out List pts) - { - var c1 = new Circle(arc.Center, arc.Radius); - - if (!Intersects(c1, circle, out pts)) - { - pts = new List(); - return false; - } - - pts = pts.Where(pt => Angle.IsBetweenRad( - arc.Center.AngleTo(pt), - arc.StartAngle, - arc.EndAngle, - arc.IsReversed)).ToList(); - - return pts.Count > 0; - } - - internal static bool Intersects(Arc arc, Line line, out List pts) - { - var c1 = new Circle(arc.Center, arc.Radius); - - if (!Intersects(c1, line, out pts)) - { - pts = new List(); - return false; - } - - pts = pts.Where(pt => Angle.IsBetweenRad( - arc.Center.AngleTo(pt), - arc.StartAngle, - arc.EndAngle, - arc.IsReversed)).ToList(); - - return pts.Count > 0; - } - - internal static bool Intersects(Arc arc, Shape shape, out List pts) - { - var pts2 = new List(); - - foreach (var geo in shape.Entities) - { - List pts3; - geo.Intersects(arc, out pts3); - pts2.AddRange(pts3); - } - - pts = pts2.Where(pt => Angle.IsBetweenRad( - arc.Center.AngleTo(pt), - arc.StartAngle, - arc.EndAngle, - arc.IsReversed)).ToList(); - - return pts.Count > 0; - } - - internal static bool Intersects(Arc arc, Polygon polygon, out List pts) - { - var pts2 = new List(); - var lines = polygon.ToLines(); - - foreach (var line in lines) - { - List pts3; - Intersects(arc, line, out pts3); - pts2.AddRange(pts3); - } - - pts = pts2.Where(pt => Angle.IsBetweenRad( - arc.Center.AngleTo(pt), - arc.StartAngle, - arc.EndAngle, - arc.IsReversed)).ToList(); - - return pts.Count > 0; - } - - internal static bool Intersects(Circle circle1, Circle circle2, out List pts) - { - var distance = circle1.Center.DistanceTo(circle2.Center); - - // check if circles are too far apart - if (distance > circle1.Radius + circle2.Radius) - { - pts = new List(); - return false; - } - - // check if one circle contains the other - if (distance < System.Math.Abs(circle1.Radius - circle2.Radius)) - { - pts = new List(); - return false; - } - - var d = circle2.Center - circle1.Center; - var a = (circle1.Radius * circle1.Radius - circle2.Radius * circle2.Radius + distance * distance) / (2.0 * distance); - var h = System.Math.Sqrt(circle1.Radius * circle1.Radius - a * a); - - var pt = new Vector( - circle1.Center.X + (a * d.X) / distance, - circle1.Center.Y + (a * d.Y) / distance); - - var i1 = new Vector( - pt.X + (h * d.Y) / distance, - pt.Y - (h * d.X) / distance); - - var i2 = new Vector( - pt.X - (h * d.Y) / distance, - pt.Y + (h * d.X) / distance); - - pts = i1 != i2 ? new List { i1, i2 } : new List { i1 }; - - return true; - } - - internal static bool Intersects(Circle circle, Line line, out List pts) - { - var d1 = line.EndPoint - line.StartPoint; - var d2 = line.StartPoint - circle.Center; - - var a = d1.X * d1.X + d1.Y * d1.Y; - var b = (d1.X * d2.X + d1.Y * d2.Y) * 2; - var c = (d2.X * d2.X + d2.Y * d2.Y) - circle.Radius * circle.Radius; - - var det = b * b - 4 * a * c; - - if ((a <= Tolerance.Epsilon) || (det < 0)) - { - pts = new List(); - return false; - } - - double t; - pts = new List(); - - if (det.IsEqualTo(0)) - { - t = -b / (2 * a); - var pt1 = new Vector(line.StartPoint.X + t * d1.X, line.StartPoint.Y + t * d1.Y); - - if (line.BoundingBox.Contains(pt1)) - pts.Add(pt1); - - return true; - } - - t = (-b + System.Math.Sqrt(det)) / (2 * a); - var pt2 = new Vector(line.StartPoint.X + t * d1.X, line.StartPoint.Y + t * d1.Y); - - if (line.BoundingBox.Contains(pt2)) - pts.Add(pt2); - - t = (-b - System.Math.Sqrt(det)) / (2 * a); - var pt3 = new Vector(line.StartPoint.X + t * d1.X, line.StartPoint.Y + t * d1.Y); - - if (line.BoundingBox.Contains(pt3)) - pts.Add(pt3); - - return true; - } - - internal static bool Intersects(Circle circle, Shape shape, out List pts) - { - pts = new List(); - - foreach (var geo in shape.Entities) - { - List pts3; - geo.Intersects(circle, out pts3); - pts.AddRange(pts3); - } - - return pts.Count > 0; - } - - internal static bool Intersects(Circle circle, Polygon polygon, out List pts) - { - pts = new List(); - var lines = polygon.ToLines(); - - foreach (var line in lines) - { - List pts3; - Intersects(circle, line, out pts3); - pts.AddRange(pts3); - } - - return pts.Count > 0; - } - - internal static bool Intersects(Line line1, Line line2, out Vector pt) - { - var a1 = line1.EndPoint.Y - line1.StartPoint.Y; - var b1 = line1.StartPoint.X - line1.EndPoint.X; - var c1 = a1 * line1.StartPoint.X + b1 * line1.StartPoint.Y; - - var a2 = line2.EndPoint.Y - line2.StartPoint.Y; - var b2 = line2.StartPoint.X - line2.EndPoint.X; - var c2 = a2 * line2.StartPoint.X + b2 * line2.StartPoint.Y; - - var d = a1 * b2 - a2 * b1; - - if (d.IsEqualTo(0.0)) - { - pt = Vector.Zero; - return false; - } - - var x = (b2 * c1 - b1 * c2) / d; - var y = (a1 * c2 - a2 * c1) / d; - - pt = new Vector(x, y); - return line1.BoundingBox.Contains(pt) && line2.BoundingBox.Contains(pt); - } - - internal static bool Intersects(Line line, Shape shape, out List pts) - { - pts = new List(); - - foreach (var geo in shape.Entities) - { - List pts3; - geo.Intersects(line, out pts3); - pts.AddRange(pts3); - } - - return pts.Count > 0; - } - - internal static bool Intersects(Line line, Polygon polygon, out List pts) - { - pts = new List(); - var lines = polygon.ToLines(); - - foreach (var line2 in lines) - { - Vector pt; - - if (Intersects(line, line2, out pt)) - pts.Add(pt); - } - - return pts.Count > 0; - } - - internal static bool Intersects(Shape shape1, Shape shape2, out List pts) - { - pts = new List(); - - for (int i = 0; i < shape1.Entities.Count; i++) - { - var geo1 = shape1.Entities[i]; - - for (int j = 0; j < shape2.Entities.Count; j++) - { - List pts2; - bool success = false; - - var geo2 = shape2.Entities[j]; - - switch (geo2.Type) - { - case EntityType.Arc: - success = geo1.Intersects((Arc)geo2, out pts2); - break; - - case EntityType.Circle: - success = geo1.Intersects((Circle)geo2, out pts2); - break; - - case EntityType.Line: - success = geo1.Intersects((Line)geo2, out pts2); - break; - - case EntityType.Shape: - success = geo1.Intersects((Shape)geo2, out pts2); - break; - - case EntityType.Polygon: - success = geo1.Intersects((Polygon)geo2, out pts2); - break; - - default: - continue; - } - - if (success) - pts.AddRange(pts2); - } - } - - return pts.Count > 0; - } - - internal static bool Intersects(Shape shape, Polygon polygon, out List pts) - { - pts = new List(); - - var lines = polygon.ToLines(); - - for (int i = 0; i < shape.Entities.Count; i++) - { - var geo = shape.Entities[i]; - - for (int j = 0; j < lines.Count; j++) - { - var line = lines[j]; - - List pts2; - - if (geo.Intersects(line, out pts2)) - pts.AddRange(pts2); - } - } - - return pts.Count > 0; - } - - internal static bool Intersects(Polygon polygon1, Polygon polygon2, out List pts) - { - pts = new List(); - - var lines1 = polygon1.ToLines(); - var lines2 = polygon2.ToLines(); - - for (int i = 0; i < lines1.Count; i++) - { - var line1 = lines1[i]; - - for (int j = 0; j < lines2.Count; j++) - { - var line2 = lines2[j]; - Vector pt; - - if (Intersects(line1, line2, out pt)) - pts.Add(pt); - } - } - - return pts.Count > 0; - } - public static List GetPartLines(Part part, double chordTolerance = 0.001) { var entities = ConvertProgram.ToGeometry(part.Program);