Ejemplo n.º 1
0
Archivo: tri.cs Proyecto: thild/sawdust
        internal bool SegmentIntersection(xy p, xy q, out xy pt1, out xy pt2)
        {
            TriSegIntersect ti = new TriSegIntersect();

            if (this.PointInside(p))
            {
                ti.Add(p);
            }
            if (this.PointInside(q))
            {
                ti.Add(q);
            }
            xy z1, z2;
            SegIntersection si = ut.GetSegIntersection(a, b, p, q, out z1, out z2);

            if (si == SegIntersection.Overlap)
            {
                pt1 = z1;
                pt2 = z2;
                return(true);
            }
            if (si == SegIntersection.Point)
            {
                ti.Add(z1);
            }

            si = ut.GetSegIntersection(b, c, p, q, out z1, out z2);
            if (si == SegIntersection.Overlap)
            {
                pt1 = z1;
                pt2 = z2;
                return(true);
            }
            if (si == SegIntersection.Point)
            {
                ti.Add(z1);
            }

            si = ut.GetSegIntersection(c, a, p, q, out z1, out z2);
            if (si == SegIntersection.Overlap)
            {
                pt1 = z1;
                pt2 = z2;
                return(true);
            }
            if (si == SegIntersection.Point)
            {
                ti.Add(z1);
            }

            if (ti.q1 == null)
            {
                pt1 = null;
                pt2 = null;
                return(false);
            }

            pt1 = ti.q1;
            if (ti.q2 != null)
            {
                pt2 = ti.q2;
            }
            else
            {
                pt2 = null;
            }
            return(true);
        }
Ejemplo n.º 2
0
 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));
 }