public static void Add(List <seg2d> segs, seg2d s) { if (!Contains(segs, s)) { segs.Add(s); } }
public static bool Contains(List <seg2d> segs, seg2d s) { foreach (seg2d seg in segs) { if (eq(seg, s)) { return(true); } } return(false); }
public static void add_seg(List <seg2d> segs, xy a, xy b) { seg2d already = find_seg(segs, a, b); if (already != null) { return; } segs.Add(new seg2d(a, b)); }
internal SegmentInfo GetInfo(seg2d s) { // since we have split every segment such that it // intersects with none others, we can now simply test the midpoint if (PointInside((s.a + s.b) / 2)) { return(SegmentInfo.Inside); } else { return(SegmentInfo.Outside); } }
public static seg2d find_seg_a(List <seg2d> segs, xy p, out xy next) { next = null; seg2d result = null; foreach (seg2d s in segs) { if (fp.eq_inches(s.a, p)) { next = s.b; result = s; break; } } return(result); }
public static bool eq(seg2d s1, seg2d s2) { if ( fp.eq_inches(s1.a, s2.a) && fp.eq_inches(s1.b, s2.b) ) { return(true); } if ( fp.eq_inches(s1.a, s2.b) && fp.eq_inches(s1.b, s2.a) ) { return(true); } return(false); }
public static void find_seg(List <seg2d> segs, xy p, out xy nextpt, out seg2d seg) { seg = null; nextpt = null; foreach (seg2d s in segs) { if (fp.eq_inches(s.a, p)) { seg = s; nextpt = s.b; break; } if (fp.eq_inches(s.b, p)) { seg = s; nextpt = s.a; break; } } Debug.Assert(seg != null); }
public seginfo2d(seg2d s, Poly2dWithExtraStuff p) { seg = s; info = p.GetInfo(s); }
public seginfo2d(seg2d s, SegmentInfo si) { seg = s; info = si; }
public static void SplitSegment(List <seginfo2d> result, seg2d s1, Poly2dWithExtraStuff p2) { foreach (seg2d s2 in p2.segs) { if (fp.eq_inches(s1.a, s2.a) && fp.eq_inches(s1.b, s2.b)) { // same segment. result.Add(new seginfo2d(s1, SegmentInfo.Same)); // nothing else can happen. stop now. return; } else if (fp.eq_inches(s1.a, s2.b) && fp.eq_inches(s1.b, s2.a)) { // same segment, but reversed result.Add(new seginfo2d(s1, SegmentInfo.Opposite)); // nothing else can happen. stop now. return; } else { xy q1; xy q2; SegIntersection si = ut.GetSegIntersection(s1, s2, out q1, out q2); if (si == SegIntersection.Point) { if ( fp.eq_inches(q1, s1.a) || fp.eq_inches(q1, s1.b) ) { // an endpoint. this doesn't count as a hit. // ignore this } else { SplitSegment(result, new seg2d(s1.a, q1), p2); SplitSegment(result, new seg2d(q1, s1.b), p2); return; } } else if (si == SegIntersection.Overlap) { SegmentInfo dir; xy v1 = (s1.b - s1.a).normalize_in_place(); xy v2 = (s2.b - s2.a).normalize_in_place(); if (fp.eq_unitvec(v1, v2)) { dir = SegmentInfo.Same; } else { dir = SegmentInfo.Opposite; } if ( fp.eq_inches(s1.a, q1) && fp.eq_inches(s1.b, q2) ) { result.Add(new seginfo2d(s1, dir)); } else if ( fp.eq_inches(s1.a, q2) && fp.eq_inches(s1.b, q1) ) { result.Add(new seginfo2d(s1, dir)); } else if (fp.eq_inches(s1.a, q1)) { result.Add(new seginfo2d(new seg2d(s1.a, q2), dir)); SplitSegment(result, new seg2d(q2, s1.b), p2); } else if (fp.eq_inches(s1.a, q2)) { result.Add(new seginfo2d(new seg2d(s1.a, q1), dir)); SplitSegment(result, new seg2d(q1, s1.b), p2); } else if (fp.eq_inches(s1.b, q1)) { SplitSegment(result, new seg2d(s1.a, q2), p2); result.Add(new seginfo2d(new seg2d(q2, s1.b), dir)); } else if (fp.eq_inches(s1.b, q2)) { SplitSegment(result, new seg2d(s1.a, q1), p2); result.Add(new seginfo2d(new seg2d(q1, s1.b), dir)); } else { // both q1 and q2 are somewhere inside s1 xy z1 = q1 - s1.a; xy z2 = q2 - s1.a; if (z1.magnitude_squared() < z2.magnitude_squared()) { // q1 is closer SplitSegment(result, new seg2d(s1.a, q1), p2); result.Add(new seginfo2d(new seg2d(q1, q2), dir)); SplitSegment(result, new seg2d(q2, s1.b), p2); } else { // q2 is closer SplitSegment(result, new seg2d(s1.a, q2), p2); result.Add(new seginfo2d(new seg2d(q2, q1), dir)); SplitSegment(result, new seg2d(q1, s1.b), p2); } } return; } } } result.Add(new seginfo2d(s1, p2)); }
public static TriangleIntersection2d CalcTriangleIntersection2d(xy a1, xy b1, xy c1, xy a2, xy b2, xy c2) { #if PP_DEBUG Console.Out.WriteLine("tri 1: a={0} b={1} c={2}", a1, b1, c1); Console.Out.WriteLine("tri 2: a={0} b={1} c={2}", a2, b2, c2); #endif TriangleIntersection2d pts = new TriangleIntersection2d(); List <seg2d> segs = new List <seg2d>(); CalcSegmentTriangleIntersection2d(pts, segs, a1, b1, a2, b2, c2); CalcSegmentTriangleIntersection2d(pts, segs, b1, c1, a2, b2, c2); CalcSegmentTriangleIntersection2d(pts, segs, c1, a1, a2, b2, c2); CalcSegmentTriangleIntersection2d(pts, segs, a2, b2, a1, b1, c1); CalcSegmentTriangleIntersection2d(pts, segs, b2, c2, a1, b1, c1); CalcSegmentTriangleIntersection2d(pts, segs, c2, a2, a1, b1, c1); TriangleIntersection2d ti = new TriangleIntersection2d(); Debug.Assert( (segs.Count >= 0) && (segs.Count <= 6) ); switch (segs.Count) { case 0: { Debug.Assert( (pts.Count == 0) || (pts.Count == 1) ); if (pts.Count == 0) { return(ti); } else // if (pts.Count == 1) { ti.Add(pts[0]); return(ti); } } case 1: case 2: case 3: case 4: case 5: case 6: { int i = 0; seg2d cur = segs[i]; ti.Add(cur.a); ti.Add(cur.b); segs.Remove(cur); xy lastpt = cur.b; while (segs.Count > 0) { xy nextpt; find_seg(segs, lastpt, out nextpt, out cur); ti.Add(nextpt); segs.Remove(cur); lastpt = nextpt; } break; } } return(ti); }