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); }
/// 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); }
/// 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; } }