internal static IEnumerable <Polygon> ToElmaPolygons(this NetTopologySuite.Geometries.Polygon poly) { var p = new Polygon(poly.Shell); p.UpdateDecomposition(); yield return(p); foreach (var linearRing in poly.Holes) { p = new Polygon(linearRing); p.UpdateDecomposition(); yield return(p); } }
internal static Polygon Ellipse(Vector mid, double a, double b, double angle, int steps) { var p = new Polygon(); double beta = -angle * Constants.DegToRad; double sinBeta = Math.Sin(beta); double cosBeta = Math.Cos(beta); for (int i = 0; i < steps; i++) { double currentAngle = i * 360.0 / steps; double alpha = currentAngle * Constants.DegToRad; double sinAlpha = Math.Sin(alpha); double cosAlpha = Math.Cos(alpha); p.Add(new Vector(mid.X + a * cosAlpha * cosBeta - b * sinAlpha * sinBeta, mid.Y + a * cosAlpha * sinBeta + b * sinAlpha * cosBeta)); } p.UpdateDecomposition(); return(p); }
internal static Polygon Connect(Polygon p1, Polygon p2, Vector v1, Vector v2, double connectRadius) { if (p1.IntersectsWith(p2)) { return(null); } bool isContained = p1.AreaHasPoint(p2[0]) || p2.AreaHasPoint(p1[0]); var p1C = new Polygon(p1); var p2C = new Polygon(p2); if (p1C.IsCounterClockwise) { p1C.ChangeOrientation(); } if (p2C.IsCounterClockwise ^ isContained) { p2C.ChangeOrientation(); } int numberOfIntersectionsP1C = 0; int numberOfIntersectionsP2C = 0; Vector p1IsectPoint = null; Vector p2IsectPoint = null; Vector.MarkDefault = VectorMark.Selected; for (int i = 0; i < p1.Vertices.Count; i++) { Vector isectPoint = GetIntersectionPoint(p1[i], p1[i + 1], v1, v2); if ((object)isectPoint != null) { p1IsectPoint = isectPoint; p1C.InsertIntersection(p1IsectPoint, Constants.Tolerance); numberOfIntersectionsP1C++; } } if (numberOfIntersectionsP1C != 1) { return(null); } for (int i = 0; i < p2.Vertices.Count; i++) { Vector isectPoint = GetIntersectionPoint(p2[i], p2[i + 1], v1, v2); if ((object)isectPoint != null) { p2IsectPoint = isectPoint; p2C.InsertIntersection(p2IsectPoint, Constants.Tolerance); numberOfIntersectionsP2C++; } } Vector.MarkDefault = VectorMark.None; if (numberOfIntersectionsP2C != 1) { return(null); } var result = new Polygon(); int p1Index = 0; int p2Index = p2C.IndexOf(p2IsectPoint); bool p1CCurrent = true; Vector p1ConnectVector = null; Vector p2ConnectVector = null; while (!(p1Index == 0 && p1CCurrent && result.Count > 0)) { if (p1CCurrent) { if (p1C[p1Index].Mark != VectorMark.Selected) { result.Add(p1C[p1Index]); } else { p1ConnectVector = p1C[p1Index + 1] - p1C[p1Index - 1]; p1ConnectVector /= p1ConnectVector.Length; var p1AngleAbs = Math.Abs(p1ConnectVector.AngleBetween(v2 - v1)); if (p1AngleAbs < Constants.Tolerance) { return(null); } p1ConnectVector *= connectRadius / Math.Sin(p1AngleAbs * Constants.DegToRad); double distance1 = (p1C[p1Index + 1] - p1C[p1Index]).Length; double distance2 = (p1C[p1Index] - p1C[p1Index - 1]).Length; if (p1ConnectVector.Length > Math.Min(distance1, distance2)) { p1ConnectVector = p1ConnectVector / p1ConnectVector.Length * Math.Min(distance1, distance2) / 2; } result.Add(p1IsectPoint - p1ConnectVector); p2ConnectVector = p2C[p2Index + 1] - p2C[p2Index - 1]; p2ConnectVector /= p2ConnectVector.Length; var p2AngleAbs = Math.Abs(p2ConnectVector.AngleBetween(v2 - v1)); if (p2AngleAbs < Constants.Tolerance) { return(null); } p2ConnectVector *= connectRadius / Math.Sin(p2AngleAbs * Constants.DegToRad); double dist1 = (p2C[p2Index + 1] - p2C[p2Index]).Length; double dist2 = (p2C[p2Index] - p2C[p2Index - 1]).Length; if (p2ConnectVector.Length > Math.Min(dist1, dist2)) { p2ConnectVector = p2ConnectVector / p2ConnectVector.Length * Math.Min(dist1, dist2) / 2; } result.Add(p2IsectPoint + p2ConnectVector); p2Index++; p1CCurrent = false; } p1Index++; p1Index = p1Index % p1C.Count; } else { if (p2C[p2Index].Mark != VectorMark.Selected) { result.Add(p2C[p2Index]); } else { result.Add(p2IsectPoint - p2ConnectVector); result.Add(p1IsectPoint + p1ConnectVector); p1CCurrent = true; } p2Index++; } } result.UpdateDecomposition(); return(result); }