/// <summary> /// Sets the index-th edge of this polygon. /// </summary> public static IImmutablePolygon <V2d> SetEdge(this IImmutablePolygon <V2d> self, int index, Line2d edge) { index = self.RepairIndex(index); var i0 = index++; var i1 = index < self.Count ? index : 0; return(self.SetPoint(i0, edge.P0).SetPoint(i1, edge.P1)); }
/// <summary> /// Gets the index-th edge of this polygon. /// </summary> public static Line2d GetEdge(this IImmutablePolygon <V2d> self, int index) { index = self.RepairIndex(index); var p0 = self.Points[index++]; var p1 = self.Points[index < self.Count ? index : 0]; return(new Line2d(p0, p1)); }
/// <summary> /// Makes index-th edge parallel to x- or y-axis. /// </summary> public static IImmutablePolygon <V2d> AlignEdge(this IImmutablePolygon <V2d> self, int index) { var e = self.GetEdge(index); if ((Math.Abs(e.P0.X - e.P1.X) < Math.Abs(e.P0.Y - e.P1.Y))) { var x = (e.P0.X + e.P1.X) * 0.5; return(self.SetEdge(index, new Line2d(new V2d(x, e.P0.Y), new V2d(x, e.P1.Y)))); } else { var y = (e.P0.Y + e.P1.Y) * 0.5; return(self.SetEdge(index, new Line2d(new V2d(e.P0.X, y), new V2d(e.P1.X, y)))); } }
/// <summary> /// Returns the index and distance of the polygon's closest point to the given query point. /// </summary> public static Tuple <int, double> QueryNearestVertex(this IImmutablePolygon <V2d> self, V2d queryPoint) { if (self.Count == 0) { return(null); } int bestIndex = 0; double bestDist = double.MaxValue; for (int i = 0; i < self.Count; i++) { var d = (queryPoint - self.Points[i]).LengthSquared; if (d < bestDist) { bestDist = d; bestIndex = i; } } return(Tuple.Create(bestIndex, bestDist.Sqrt())); }
/// <summary> /// Maps arbitrary index into valid range. /// </summary> public static int RepairIndex <T>(this IImmutablePolygon <T> self, int index) => RepairIndex(self.Count, index);
/// <summary> /// Returns new polygon with point transformed. /// </summary> public static IImmutablePolygon <V2d> TransformPoint(this IImmutablePolygon <V2d> self, int index, M33d trafo) => self.SetPoint(index, trafo.TransformPos(self.Points[index]));
/// <summary> /// Returns new polygon with point moved. /// </summary> public static IImmutablePolygon <V2d> MovePoint(this IImmutablePolygon <V2d> self, int index, V2d delta) => self.SetPoint(index, self.Points[index] + delta);
/// <summary> /// Ensures that the outline is oriented clockwise. /// </summary> public static IImmutablePolygon <V2d> ToClockwise(this IImmutablePolygon <V2d> self) => self.ToPolygon2d().IsCcw() ? new ImmutablePolygon <V2d>(self.Points.Reverse()) : self;
/// <summary> /// Converts this IImmutablePolygon(of V2d) to a Polygon2d. /// </summary> public static Polygon2d ToPolygon2d(this IImmutablePolygon <V2d> self) => new Polygon2d(self.Points);
/// <summary> /// Ensures that the outline is oriented counter-clockwise. /// </summary> public static IImmutablePolygon <V2d> ToCounterClockwise(this IImmutablePolygon <V2d> self) { return(self.ToPolygon2d().IsCcw() ? self : new ImmutablePolygon <V2d>(self.Points.Reverse())); }
/// <summary> /// Converts this IImmutablePolygon(of V2d) to a Polygon2d. /// </summary> public static Polygon2d ToPolygon2d(this IImmutablePolygon <V2d> self) { return(new Polygon2d(self.Points)); }