public Orientation CheckPointOrientation(Vector2d pt) { var segments = Segments.ToArray(); var onBorder = segments.Any(n => Vec.CheckOrientation(pt, n.A, n.B) == Orientation.ON_SEGMENT); if (onBorder) { return(Orientation.BORDER); } else { var ray = new Ray2d(pt, new Vector2d(1, 0)); int count = 0; foreach (var segmentI in segments) { Vector2d?intersection; if (ray.RayWithSegment(segmentI, out intersection)) { count++; } } var result = PointInPolygon(_lst.ToArray(), pt); if (result) { return(Orientation.INSIDE); } return(Orientation.OUTSIDE); } }
public Polygon2d ConvexHull() { if (_points.Count < 3) { return(new Polygon2d(_points)); } var ordered = _points.ToArray(); Array.Sort(ordered, new OriginComparer()); var lu = new List <Vector2d> { ordered[0], ordered[1] }; for (int i = 2; i < ordered.Length; i++) { var p = ordered[i]; lu.Add(p); while (lu.Count > 2 && Vec.CheckOrientation(lu[lu.Count - 3], lu[lu.Count - 2], lu[lu.Count - 1]) != Orientation.RIGHT) { lu.RemoveAt(lu.Count - 2); } } var limit = lu.Count + 1; for (var i = ordered.Length - 1; i >= 0; i--) { var p = ordered[i]; lu.Add(p); while (lu.Count > limit && Vec.CheckOrientation(lu[lu.Count - 3], lu[lu.Count - 2], lu[lu.Count - 1]) != Orientation.RIGHT) { lu.RemoveAt(lu.Count - 2); } } lu.RemoveAt(lu.Count - 1); var poly = new Polygon2d(lu); return(poly); }
public string[] ProcessTask(string[] stdIn) { var segment = ReadSegment(stdIn[0]); var segCount = ReadSegmentsCount(stdIn[1]); var arr = new string[segCount]; for (int i = 0; i < segCount; i++) { var p = ReadVector(stdIn[i + 2]); arr[i] = Parse.ParseOrientation(Vec.CheckOrientation(p, segment.A, segment.B)); } return(arr); }
public Orientation OrientatePoint(Vector2d p) { var o1 = Vec.CheckOrientation(p, _a, _b); var o2 = Vec.CheckOrientation(p, _b, _c); var o3 = Vec.CheckOrientation(p, _c, _a); ; if (o1 == o2 && o2 == o3 && (o3 == Orientation.RIGHT || o3 == Orientation.LEFT)) { return(Orientation.INSIDE); } if (o1 == Orientation.ON_SEGMENT || o2 == Orientation.ON_SEGMENT || o3 == Orientation.ON_SEGMENT) { return(Orientation.BORDER); } return(Orientation.OUTSIDE); }
public bool Intersection(Segment2d segment, out Vector2d intersection, out Segment2d seg) { var x1 = A.X; var y1 = A.Y; var x2 = B.X; var y2 = B.Y; var x3 = segment.A.X; var y3 = segment.A.Y; var x4 = segment.B.X; var y4 = segment.B.Y; var denom = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4); if (Math.Abs(denom) > float.Epsilon) { var t = ((x1 - x3) * (y3 - y4) - (y1 - y3) * (x3 - x4)) / denom; var u = ((x1 - x2) * (y1 - y3) - (y1 - y2) * (x1 - x3)) / -denom; if (Vec.InOpenRange(t, 0, 1) && Vec.InOpenRange(u, 0, 1)) { intersection = new Vector2d( x1 + t * (x2 - x1), y1 + t * (y2 - y1) ); seg = NaN; return(true); } } else { var onSegment = new SortedSet <Vector2d>(new OriginComparer()); var o1 = Vec.CheckOrientation(segment.A, A, B); var o2 = Vec.CheckOrientation(segment.B, A, B); var o3 = Vec.CheckOrientation(A, segment.A, segment.B); var o4 = Vec.CheckOrientation(B, segment.A, segment.B); //shit code if (o1 == Orientation.ON_SEGMENT) { onSegment.Add(segment.A); } if (o2 == Orientation.ON_SEGMENT) { onSegment.Add(segment.B); } if (o3 == Orientation.ON_SEGMENT) { onSegment.Add(A); } if (o4 == Orientation.ON_SEGMENT) { onSegment.Add(B); } var or = new[] { o1, o2, o3, o4 }; if (o1 == o2 && o2 == o3 & o3 == o4 && o4 == Orientation.ONLINE) { intersection = Vector2d.NaN; seg = NaN; return(false); } if (o1 == o2 && o2 == o3 & o3 == o4 && o4 == Orientation.ON_SEGMENT) { intersection = Vector2d.NaN; seg = segment; return(true); } if (or.Any(n => n == Orientation.LEFT || n == Orientation.RIGHT)) { intersection = Vector2d.NaN; seg = NaN; return(false); } if (onSegment.Count == 1) { intersection = onSegment.First(); seg = NaN; return(true); } if (onSegment.Count > 1) { var arr = onSegment.ToArray(); double minDist = double.MaxValue; // don't need var a = Vector2d.NaN; var b = Vector2d.NaN; for (int i = 0; i < arr.Length - 1; i++) { var cur = (i + 1) % onSegment.Count; var next = (cur + 1) % onSegment.Count; //govno code var sqrDist = arr[cur].SqrDist(arr[next]); if (sqrDist < minDist) { minDist = sqrDist; a = arr[cur]; b = arr[next]; } } intersection = Vector2d.NaN; seg = new Segment2d(a, b); return(true); } } intersection = Vector2d.NaN; seg = NaN; return(false); }