public static double Distance2(Vector2 point, IClosedPolyline line) { var prevVector = line.Vertices.Last() - point; var prevNorm2 = prevVector.Norm2; var answer = prevNorm2; foreach (var vertex in line.Vertices) { var vector = vertex - point; var norm2 = vector.Norm2; var displacement = vector - prevVector; if ((prevVector * displacement) * (vector * displacement) > 0) { answer = Math.Min(answer, norm2); } else { answer = Math.Min(answer, BasicMath.Sqr(prevVector.Cross(vector)) / displacement.Norm2); } prevVector = vector; prevNorm2 = norm2; } return(answer); }
public static int WindingNumber(this IClosedPolyline @this, Vector2 point) { var answer = 0; var prevVector = @this.Vertices.Last() - point; foreach (var vertex in @this.Vertices) { var vector = vertex - point; if (vector.Y * prevVector.Y < 0 && // edge crosses X axis vector.Y * prevVector.Cross(vector) > 0) // edge crosses positive half of X axis { if (vector.Y > 0) { answer++; // counterclockwise crossing } else { answer--; // clockwise crossing } } prevVector = vector; } return(answer); }
public VerticalPrism(IClosedPolyline @base, Interval zRange) : base(@base, zRange, isClosed: true) { if (!_isCounterclockwise) { throw new ArgumentException("@base has to be counterclockwise", "@base"); } _basePolygon = new Polygon(@base); }
public static void FindClosestPoint(this IClosedPolyline @this, Vector2 point, out Vector2 closestPoint, out double distance2) { var prevVector = @this.Vertices.Last() - point; var prevNorm2 = prevVector.Norm2; closestPoint = @this.Vertices.Last(); distance2 = prevNorm2; foreach (var vertex in @this.Vertices) { var vector = vertex - point; var norm2 = vector.Norm2; var displacement = vector - prevVector; var vectorDotDisplacement = vector * displacement; if ((prevVector * displacement) * vectorDotDisplacement > 0) { if (norm2 < distance2) { closestPoint = vertex; distance2 = norm2; } } else { var displacementNorm2 = displacement.Norm2; var perpendicularLength2 = BasicMath.Sqr(prevVector.Cross(vector)) / displacementNorm2; if (perpendicularLength2 < distance2) { closestPoint = vertex - vectorDotDisplacement * displacement / displacementNorm2; distance2 = perpendicularLength2; } } prevVector = vector; prevNorm2 = norm2; } }
public static IClosedPolyline TranslateBy(this IClosedPolyline @this, Vector2 translation) { return(new ClosedPolyline(@this.Vertices.Select(v => v + translation))); }
public static double DistanceTo(this Vector2 @this, IClosedPolyline line) { return(Math.Sqrt(Distance2(@this, line))); }
public static IClosedPolyline FromBoxCoords(this IClosedPolyline @this, Box2 box) { return(new ClosedPolyline(@this.Vertices.Select(v => v.FromBoxCoords(box)))); }
public void AddContour(IClosedPolyline contour) { _contours.Add(contour); }
public static Segment2 GetEdge(this IClosedPolyline @this, int index) { var vertices = @this.Vertices; return(new Segment2(vertices.ElementAtCyclic(index), vertices.ElementAtCyclic(index + 1))); }
public static Vector2 GetVertex(this IClosedPolyline @this, int index) { return(@this.Vertices.ElementAtCyclic(index)); }
public static Vector2 Normal(this IClosedPolyline @this, int index) { return(Displacement(@this, index).Rotate270().Normalized); }
public static IClosedPolyline ApplyInv(this Rotation2 @this, IClosedPolyline line) { return(new ClosedPolyline(line.Vertices.Select(v => @this.ApplyInv(v)))); }
private static ClipperContour MinusConvertToFixedPoint(IClosedPolyline p, Box2 range) { return((from vertex in p.Vertices select MinusConvertToFixedPoint(vertex, range)).ToList()); }
public static Vector2 Displacement(this IClosedPolyline @this, int index) { var vertices = @this.Vertices; return(vertices.ElementAtCyclic(index + 1) - vertices.ElementAtCyclic(index)); }
public static IClosedPolyline AsReverse(this IClosedPolyline @this) { return(new ClosedPolyline(@this.Vertices.AsReverse())); }
public Polygon(IClosedPolyline contour) { _contours = contour.AsSingleton(); _boundingBox = Box2.Hull(contour.Vertices); }
public ClosedPolyline(IClosedPolyline line) { _vertices = line.Vertices; }