From 25fa09178b7d0d0befa708e93ea5316ef381caa0 Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Fri, 22 May 2015 10:23:27 +0200 Subject: Update to 2Geom revision 2396 (bzr r14059.2.16) --- src/2geom/line.cpp | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 65 insertions(+), 5 deletions(-) (limited to 'src/2geom/line.cpp') diff --git a/src/2geom/line.cpp b/src/2geom/line.cpp index 35cf2d379..8bea33638 100644 --- a/src/2geom/line.cpp +++ b/src/2geom/line.cpp @@ -62,7 +62,7 @@ void Line::setCoefficients (Coord a, Coord b, Coord c) { if (a == 0 && b == 0) { if (c != 0) { - THROW_LOGICALERROR("the passed coefficients gives the empty set"); + THROW_LOGICALERROR("the passed coefficients give the empty set"); } _initial = Point(0,0); _final = Point(0,0); @@ -70,20 +70,20 @@ void Line::setCoefficients (Coord a, Coord b, Coord c) } if (a == 0) { // b must be nonzero - _initial = Point(0, c / b); + _initial = Point(0, -c / b); _final = _initial; _final[X] = 1; return; } if (b == 0) { - _initial = Point(c / a, 0); + _initial = Point(-c / a, 0); _final = _initial; _final[Y] = 1; return; } - _initial = Point(c / a, 0); - _final = Point(0, c / b); + _initial = Point(-c / a, 0); + _final = Point(0, -c / b); } void Line::coefficients(Coord &a, Coord &b, Coord &c) const @@ -217,6 +217,66 @@ Coord Line::timeAt(Point const &p) const } } +std::vector Line::intersect(Line const &other) const +{ + std::vector result; + + Point v1 = versor(); + Point v2 = other.versor(); + Coord cp = cross(v1, v2); + if (cp == 0) return result; + + Point odiff = other.initialPoint() - initialPoint(); + Coord t1 = cross(odiff, v2) / cp; + Coord t2 = cross(odiff, v1) / cp; + result.push_back(ShapeIntersection(*this, other, t1, t2)); + return result; +} + +std::vector Line::intersect(Ray const &r) const +{ + Line other(r); + std::vector result = intersect(other); + filter_ray_intersections(result, false, true); + return result; +} + +std::vector Line::intersect(LineSegment const &ls) const +{ + Line other(ls); + std::vector result = intersect(other); + filter_line_segment_intersections(result, false, true); + return result; +} + + + +void filter_line_segment_intersections(std::vector &xs, bool a, bool b) +{ + Interval unit(0, 1); + std::vector::reverse_iterator i = xs.rbegin(), last = xs.rend(); + while (i != last) { + if ((a && !unit.contains(i->first)) || (b && !unit.contains(i->second))) { + xs.erase((++i).base()); + } else { + ++i; + } + } +} + +void filter_ray_intersections(std::vector &xs, bool a, bool b) +{ + Interval unit(0, 1); + std::vector::reverse_iterator i = xs.rbegin(), last = xs.rend(); + while (i != last) { + if ((a && i->first < 0) || (b && i->second < 0)) { + xs.erase((++i).base()); + } else { + ++i; + } + } +} + namespace detail { -- cgit v1.2.3