Beispiel #1
0
        public bool Contains(LineSeg ll)
        {
            Vector s = ll.Start; Vector e = ll.End;

            return(m_xmin <= s.X && s.X <= m_xmax &&
                   m_xmin <= e.X && e.X <= m_xmax &&
                   m_ymin <= s.Y && s.Y <= m_ymax &&
                   m_ymin <= e.Y && e.Y <= m_ymax);
        }
Beispiel #2
0
        /// Intersection test for line segments..
        public bool Intersects(LineSeg l)
        {
            // Seperating axis method.
            Vector sp  = l.Start;
            Vector ep  = l.End;
            Vector dir = l.Dir;

            // Projection onto the x & y axis & check for overlap
            if (!intervalsOverlap(sp.X, ep.X, m_xmin, m_xmax))
            {
                return(false);
            }
            if (!intervalsOverlap(sp.Y, ep.Y, m_ymin, m_ymax))
            {
                return(false);
            }

            // Test line-sidedness
            Vector ll   = new Vector(m_xmin, m_ymin) - sp;
            int    side = dir.Side(ll);

            if (side == 0) // the point lies right on the line
            {
                return(true);
            }

            Vector lr = new Vector(m_xmax, m_ymin) - sp;

            if (side != dir.Side(lr))
            {
                return(true);
            }

            Vector ul = new Vector(m_xmin, m_ymax) - sp;

            if (side != dir.Side(ul))
            {
                return(true);
            }

            Vector ur = new Vector(m_xmax, m_ymax) - sp;

            if (side != dir.Side(ur))
            {
                return(true);
            }

            // If we got here, all 4 corners lie on the same side of the line
            return(false);
        }
Beispiel #3
0
        /// Overlay two lines with given tolerances.
        /// (see Vector.GetParTolerance for the parallel tolerance; the
        ///  distance tolerance should be a distance^2.)
        /// Outputs are: the overlap itself,
        ///  any leftover bits prior to the overlap,
        ///  any leftover bits afterwards,
        ///  and two booleans indicating which lineseg 'owns' the leftovers.
        public static void Overlay(LineSeg a,
                                   LineSeg b,
                                   double par_tolerance,
                                   double sep_dist_squared,
                                   out LineSeg prior,
                                   out bool a_is_prior,
                                   out LineSeg overlap,
                                   out LineSeg after,
                                   out bool a_is_after)
        {
            prior      = null; overlap = null; after = null;
            a_is_prior = false; a_is_after = false;

            // If they aren't parallel, we're done.
            if (!Vector.AreParallel(a.Dir, b.Dir, par_tolerance))
            {
                return;
            }

            double a_tval; // the t value for line a where the overlap with b may start
            double distsq = a.PointDistanceSq(b.Start, out a_tval);

            if (distsq > sep_dist_squared) // too far away
            {
                return;
            }

            double a_nd_tval; // t value where the end of b overlaps line a

            distsq = a.PointDistanceSq(b.End, out a_nd_tval);
            if (distsq > sep_dist_squared) // too far away
            {
                return;
            }

            // The lines themselves are overlapping but the line
            //  segments might not be, in which case neither of b's endpoints
            //   will generate a tval in the [0,1] interval.

            double st_t = Math.Min(a_tval, a_nd_tval); // Order things so a
            double nd_t = Math.Max(a_tval, a_nd_tval); // line from st_t to

            // nd_t will be
            // parallel to A.

            // If the overlap is completely outside of a, done:
            if (st_t > 1.0)
            {
                return;
            }
            if (nd_t < 0.0)
            {
                return;
            }

            // There's an overlap.
            // Threshold a_tval and a_nd_tval into [0,1] for the overlapping portion.
            double clamp_st_t = Math.Max(st_t, 0.0);
            double clamp_nd_t = Math.Min(nd_t, 1.0);

            overlap = new LineSeg(a.Start + (clamp_st_t * a.Dir),
                                  ((clamp_nd_t - clamp_st_t) * a.Dir));

            // Don't return overlaps shorter than the error distance...
            if (overlap.Dir.LengthSq < sep_dist_squared)
            {
                overlap = null;
                return;
            }

            // Find any leftover, non-overlapping portions of a and b:

            if (st_t < 0.0) // some of line b is before line a's start
            {
                prior      = FromEndpoints(a.Start + (st_t * a.Dir), a.Start);
                a_is_prior = false;
            }
            else if (st_t > 0.0) // some of line a is left over
            {
                prior      = FromEndpoints(a.Start, a.Start + (st_t * a.Dir));
                a_is_prior = true;
            }

            if (nd_t > 1.0) // Some of 'b' is after a's end:
            {
                after      = FromEndpoints(a.End, a.Start + (nd_t * a.Dir));
                a_is_after = false;
            }
            else if (nd_t < 1.0) // some of 'a' leftover.
            {
                after      = FromEndpoints(a.Start + (nd_t * a.Dir), a.End);
                a_is_after = true;
            }

            // Null out the leftovers if they aren't larger than the tolerance:
            if (prior != null && prior.Dir.LengthSq < sep_dist_squared)
            {
                prior = null;
            }
            if (after != null && after.Dir.LengthSq < sep_dist_squared)
            {
                after = null;
            }
        }