Code

Use the line intersection routines in 2geom/line.h instead of the deprecated ones...
authordvlierop2 <dvlierop2@users.sourceforge.net>
Sun, 12 Apr 2009 12:59:26 +0000 (12:59 +0000)
committerdvlierop2 <dvlierop2@users.sourceforge.net>
Sun, 12 Apr 2009 12:59:26 +0000 (12:59 +0000)
src/2geom/geom.h
src/box3d.cpp
src/display/canvas-axonomgrid.cpp
src/line-snapper.cpp
src/live_effects/lpe-line_segment.cpp
src/snapped-line.cpp
src/snapped-line.h

index 4e7095372ed0adc8551aa5897ea9d5e7363864c7..9233696d74fc631d07380c55c56eb18e1a2b2242 100644 (file)
@@ -57,7 +57,7 @@ intersector_ccw(const Geom::Point& p0, const Geom::Point& p1,
 
 /* intersectors */
 
-#if 1
+#if 0
 // Use the new routines provided in line.h
 
 IntersectorKind
@@ -76,7 +76,7 @@ line_twopoint_intersect(Geom::Point const &p00, Geom::Point const &p01,
                        Geom::Point &result);
 #endif
 
-#if 1
+#if 0
 std::vector<Geom::Point>
 rect_line_intersect(Geom::Point const &E, Geom::Point const &F,
                     Geom::Point const &p0, Geom::Point const &p1);
index 34ce7a27fa0e824ea8bf8afc7e053a1d42fba2aa..5cffa66d954bcfdcd4ef7e8a110c338c5a31f5b1 100644 (file)
@@ -31,7 +31,7 @@
 #include "line-geometry.h"
 #include "persp3d-reference.h"
 #include "uri.h"
-#include <2geom/geom.h>
+#include <2geom/line.h>
 #include "sp-guide.h"
 #include "sp-namedview.h"
 #include "preferences.h"
@@ -675,17 +675,32 @@ void box3d_corners_for_PLs (const SPBox3D * box, Proj::Axis axis,
 static bool
 box3d_half_line_crosses_joining_line (Geom::Point const &A, Geom::Point const &B,
                                       Geom::Point const &C, Geom::Point const &D) {
-    Geom::Point E; // the point of intersection
     Geom::Point n0 = (B - A).ccw();
     double d0 = dot(n0,A);
 
     Geom::Point n1 = (D - C).ccw();
     double d1 = dot(n1,C);
-    Geom::IntersectorKind intersects = Geom::line_intersection(n0, d0, n1, d1, E);
-    if (intersects == Geom::coincident || intersects == Geom::parallel) {
+
+    Geom::Line lineAB(A,B);
+    Geom::Line lineCD(C,D);
+
+    Geom::OptCrossing inters = Geom::OptCrossing(); // empty by default
+       try
+       {
+               inters = Geom::intersection(lineAB, lineCD);
+       }
+       catch (Geom::InfiniteSolutions e)
+       {
+               // We're probably dealing with parallel lines, so they don't really cross
+               return false;
+       }
+
+    if (!inters) {
         return false;
     }
 
+    Geom::Point E = lineAB.pointAt((*inters).ta); // the point of intersection
+
     if ((dot(C,n0) < d0) == (dot(D,n0) < d0)) {
         // C and D lie on the same side of the line AB
         return false;
index 9c6126b7c91a93aca0e525bbc784bc6b26b9403c..1a7c01c168a6caa94682b5b3a020c964f04efb59 100644 (file)
@@ -20,7 +20,7 @@
 #include "sp-canvas-util.h"
 #include "canvas-axonomgrid.h"
 #include "util/mathfns.h"
-#include "2geom/geom.h"
+#include "2geom/line.h"
 #include "display-forward.h"
 #include <libnr/nr-pixops.h>
 
@@ -713,33 +713,47 @@ CanvasAxonomGridSnapper::_getSnapLines(Geom::Point const &p) const
     double y_proj_along_x_max = Inkscape::Util::round_to_upper_multiple_plus(y_proj_along_x, scaled_spacing_v, grid->origin[Geom::Y]);
     double y_proj_along_x_min = Inkscape::Util::round_to_lower_multiple_plus(y_proj_along_x, scaled_spacing_v, grid->origin[Geom::Y]);
 
+    // Calculate the versor for the angled grid lines
+    Geom::Point vers_x = Geom::Point(1, -grid->tan_angle[X]);
+    Geom::Point vers_z = Geom::Point(1, grid->tan_angle[Z]);
+
     // Calculate the normal for the angled grid lines
-    Geom::Point norm_x = Geom::rot90(Geom::Point(1, -grid->tan_angle[X]));
-    Geom::Point norm_z = Geom::rot90(Geom::Point(1, grid->tan_angle[Z]));
+    Geom::Point norm_x = Geom::rot90(vers_x);
+    Geom::Point norm_z = Geom::rot90(vers_z);
 
-    // The four angled grid lines form a parallellogram, enclosing the point
-    // One of the two vertical grid lines divides this parallellogram in two triangles
+    // The four angled grid lines form a parallelogram, enclosing the point
+    // One of the two vertical grid lines divides this parallelogram in two triangles
     // We will now try to find out in which half (i.e. triangle) our point is, and return
     // only the three grid lines defining that triangle
 
     // The vertical grid line is at the intersection of two angled grid lines.
     // Now go find that intersection!
-    Geom::Point result;
-    Geom::IntersectorKind is = Geom::line_intersection(norm_x, norm_x[Geom::Y]*y_proj_along_x_max,
-                                           norm_z, norm_z[Geom::Y]*y_proj_along_z_max,
-                                           result);
-
-    // Determine which half of the parallellogram to use
+    Geom::Point p_x(0, y_proj_along_x_max);
+    Geom::Line line_x(p_x, p_x + vers_x);
+    Geom::Point p_z(0, y_proj_along_z_max);
+       Geom::Line line_z(p_z, p_z + vers_z);
+
+    Geom::OptCrossing inters = Geom::OptCrossing(); // empty by default
+       try
+       {
+               inters = Geom::intersection(line_x, line_z);
+       }
+       catch (Geom::InfiniteSolutions e)
+       {
+               // We're probably dealing with parallel lines; this is useless!
+               return s;
+       }
+
+    // Determine which half of the parallelogram to use
     bool use_left_half = true;
     bool use_right_half = true;
 
-    if (is == Geom::intersects) {
-        use_left_half = (p[Geom::X] - grid->origin[Geom::X]) < result[Geom::X];
+    if (inters) {
+        Geom::Point inters_pt = line_x.pointAt((*inters).ta);
+       use_left_half = (p[Geom::X] - grid->origin[Geom::X]) < inters_pt[Geom::X];
         use_right_half = !use_left_half;
     }
 
-    //std::cout << "intersection at " << result << " leads to use_left_half = " << use_left_half << " and use_right_half = " << use_right_half << std::endl;
-
     // Return the three grid lines which define the triangle that encloses our point
     // If we didn't find an intersection above, all 6 grid lines will be returned
     if (use_left_half) {
index f6a6be74e6456049dbb32bc06258c18597af08e0..73f46c0a24be1fff9b6f0b7209cebd45f927b35e 100644 (file)
@@ -11,7 +11,7 @@
  * Released under GNU GPL, read the file 'COPYING' for more information
  */
 
-#include <2geom/geom.h>
+#include <2geom/line.h>
 #include "line-snapper.h"
 #include "snapped-line.h"
 #include <gtk/gtk.h>
@@ -75,23 +75,23 @@ void Inkscape::LineSnapper::constrainedSnap(SnappedConstraints &sc,
 
     for (LineList::const_iterator i = lines.begin(); i != lines.end(); i++) {
         if (Geom::L2(c.getDirection()) > 0) { // Can't do a constrained snap without a constraint
-            /* Normal to the line we're trying to snap along */
-            Geom::Point const n(Geom::rot90(Geom::unit_vector(c.getDirection())));
-
-            Geom::Point const point_on_line = c.hasPoint() ? c.getPoint() : p;
-
-            /* Constant term of the line we're trying to snap along */
-            Geom::Coord const q0 = dot(n, point_on_line);
-            /* Constant term of the grid or guide line */
-            Geom::Coord const q1 = dot(i->first, i->second);
-
-            /* Try to intersect this line with the target line */
-            Geom::Point t_2geom(NR_HUGE, NR_HUGE);
-            Geom::IntersectorKind const k = Geom::line_intersection(n, q0, i->first, q1, t_2geom);
-            Geom::Point t(t_2geom);
+               Geom::Point const point_on_line = c.hasPoint() ? c.getPoint() : p;
+            Geom::Line line1(point_on_line, point_on_line + c.getDirection());
+            Geom::Line line2(i->second, i->second + Geom::rot90(i->first));
+            Geom::OptCrossing inters = Geom::OptCrossing(); // empty by default
+            try
+            {
+               inters = Geom::intersection(line1, line2);
+            }
+            catch (Geom::InfiniteSolutions e)
+            {
+               // We're probably dealing with parallel lines, so snapping doesn't make any sense here
+               continue; // jump to the next iterator in the for-loop
+            }
 
-            if (k == Geom::intersects) {
-                const Geom::Coord dist = Geom::L2(t - p);
+                       if (inters) {
+                               Geom::Point t = line1.pointAt((*inters).ta);
+               const Geom::Coord dist = Geom::L2(t - p);
                 if (dist < getSnapperTolerance()) {
                                // When doing a constrained snap, we're already at an intersection.
                     // This snappoint is therefore fully constrained, so there's no need
index 9a7d3cfbca60ac56a042c9f9eedf1566a4072f15..df5619002a3b56b88d94118e8c1dd62693d0729a 100644 (file)
@@ -53,29 +53,29 @@ LPELineSegment::doBeforeEffect (SPLPEItem *lpeitem)
 std::vector<Geom::Path>
 LPELineSegment::doEffect_path (std::vector<Geom::Path> const & path_in)
 {
-    using namespace Geom;
     std::vector<Geom::Path> output;
 
     A = initialPoint(path_in);
     B = finalPoint(path_in);
 
-    std::vector<Point> intersections = rect_line_intersect(bboxA, bboxB, A, B);
+    Geom::Rect dummyRect(bboxA, bboxB);
+    boost::optional<Geom::LineSegment> intersection_segment = Geom::rect_line_intersect(dummyRect, Geom::Line(A, B));
 
-    if (intersections.size() < 2) {
+    if (!intersection_segment) {
         g_print ("Possible error - no intersection with limiting bounding box.\n");
         return path_in;
     }
 
     if (end_type == END_OPEN_INITIAL || end_type == END_OPEN_BOTH) {
-        A = intersections[0];
+        A = (*intersection_segment).initialPoint();
     }
 
     if (end_type == END_OPEN_FINAL || end_type == END_OPEN_BOTH) {
-        B = intersections[1];
+        B = (*intersection_segment).finalPoint();
     }
 
     Geom::Path path(A);
-    path.appendNew<LineSegment>(B);
+    path.appendNew<Geom::LineSegment>(B);
 
     output.push_back(path);
 
index 27e024821e418ddbdcaf9dfc6c66b4a656a722e7..3ebbeaf70d3962e5b38baa4bdbe06249707d1ba5 100644 (file)
@@ -9,7 +9,7 @@
  */
 
 #include "snapped-line.h"
-#include <2geom/geom.h>
+#include <2geom/line.h>
 
 Inkscape::SnappedLineSegment::SnappedLineSegment(Geom::Point const &snapped_point, Geom::Coord const &snapped_distance, SnapSourceType const &source, SnapTargetType const &target, Geom::Coord const &snapped_tolerance, bool const &always_snap, Geom::Point const &start_point_of_line, Geom::Point const &end_point_of_line)
     : _start_point_of_line(start_point_of_line), _end_point_of_line(end_point_of_line)
@@ -49,16 +49,22 @@ Inkscape::SnappedLineSegment::~SnappedLineSegment()
 
 Inkscape::SnappedPoint Inkscape::SnappedLineSegment::intersect(SnappedLineSegment const &line) const
 {
-    Geom::Point intersection_2geom(NR_HUGE, NR_HUGE);
-    Geom::IntersectorKind result = segment_intersect(_start_point_of_line, _end_point_of_line,
-                                                       line._start_point_of_line, line._end_point_of_line,
-                                                       intersection_2geom);
-      Geom::Point intersection(intersection_2geom);
-
-    if (result == Geom::intersects) {
-        /* If a snapper has been told to "always snap", then this one should be preferred
+    Geom::OptCrossing inters = Geom::OptCrossing(); // empty by default
+       try
+       {
+               inters = Geom::intersection(getLineSegment(), line.getLineSegment());
+       }
+       catch (Geom::InfiniteSolutions e)
+       {
+               // We're probably dealing with parallel lines, so they don't really cross
+               inters = Geom::OptCrossing();
+       }
+
+    if (inters) {
+        Geom::Point inters_pt = getLineSegment().pointAt((*inters).ta);
+       /* If a snapper has been told to "always snap", then this one should be preferred
          * over the other, if that other one has not been told so. (The preferred snapper
-         * will be labelled "primary" below)
+         * will be labeled "primary" below)
         */
         bool const c1 = this->getAlwaysSnap() && !line.getAlwaysSnap(); //do not use _tolerance directly!
         /* If neither or both have been told to "always snap", then cast a vote based on
@@ -70,14 +76,14 @@ Inkscape::SnappedPoint Inkscape::SnappedLineSegment::intersect(SnappedLineSegmen
         bool const use_this_as_primary = c1 || c2;
         Inkscape::SnappedLineSegment const *primarySLS = use_this_as_primary ? this : &line;
         Inkscape::SnappedLineSegment const *secondarySLS = use_this_as_primary ? &line : this;
-        Geom::Coord primaryDist = use_this_as_primary ? Geom::L2(intersection_2geom - this->getPoint()) : Geom::L2(intersection_2geom - line.getPoint());
-        Geom::Coord secondaryDist = use_this_as_primary ? Geom::L2(intersection_2geom - line.getPoint()) : Geom::L2(intersection_2geom - this->getPoint());
-        return SnappedPoint(intersection, SNAPSOURCE_UNDEFINED, SNAPTARGET_PATH_INTERSECTION, primaryDist, primarySLS->getTolerance(), primarySLS->getAlwaysSnap(), true, true,
+        Geom::Coord primaryDist = use_this_as_primary ? Geom::L2(inters_pt - this->getPoint()) : Geom::L2(inters_pt - line.getPoint());
+        Geom::Coord secondaryDist = use_this_as_primary ? Geom::L2(inters_pt - line.getPoint()) : Geom::L2(inters_pt - this->getPoint());
+        return SnappedPoint(inters_pt, SNAPSOURCE_UNDEFINED, SNAPTARGET_PATH_INTERSECTION, primaryDist, primarySLS->getTolerance(), primarySLS->getAlwaysSnap(), true, true,
                                           secondaryDist, secondarySLS->getTolerance(), secondarySLS->getAlwaysSnap());
     }
 
     // No intersection
-    return SnappedPoint(intersection, SNAPSOURCE_UNDEFINED, SNAPTARGET_UNDEFINED, NR_HUGE, 0, false, false, false, NR_HUGE, 0, false);
+    return SnappedPoint(Geom::Point(NR_HUGE, NR_HUGE), SNAPSOURCE_UNDEFINED, SNAPTARGET_UNDEFINED, NR_HUGE, 0, false, false, false, NR_HUGE, 0, false);
 };
 
 
@@ -123,13 +129,20 @@ Inkscape::SnappedPoint Inkscape::SnappedLine::intersect(SnappedLine const &line)
     // One could be a grid line, whereas the other could be a guide line
     // The point of intersection should be considered for snapping, but might be outside the snapping range
 
-    Geom::Point intersection_2geom(NR_HUGE, NR_HUGE);
-    Geom::IntersectorKind result = Geom::line_intersection(getNormal(), getConstTerm(),
-                                   line.getNormal(), line.getConstTerm(), intersection_2geom);
-    Geom::Point intersection(intersection_2geom);
-
-    if (result == Geom::intersects) {
-        /* If a snapper has been told to "always snap", then this one should be preferred
+    Geom::OptCrossing inters = Geom::OptCrossing(); // empty by default
+       try
+       {
+               inters = Geom::intersection(getLine(), line.getLine());
+       }
+       catch (Geom::InfiniteSolutions e)
+       {
+               // We're probably dealing with parallel lines, so they don't really cross
+               inters = Geom::OptCrossing();
+       }
+
+    if (inters) {
+       Geom::Point inters_pt = getLine().pointAt((*inters).ta);
+       /* If a snapper has been told to "always snap", then this one should be preferred
          * over the other, if that other one has not been told so. (The preferred snapper
          * will be labelled "primary" below)
         */
@@ -142,16 +155,16 @@ Inkscape::SnappedPoint Inkscape::SnappedLine::intersect(SnappedLine const &line)
         bool const use_this_as_primary = c1 || c2;
         Inkscape::SnappedLine const *primarySL = use_this_as_primary ? this : &line;
         Inkscape::SnappedLine const *secondarySL = use_this_as_primary ? &line : this;
-        Geom::Coord primaryDist = use_this_as_primary ? Geom::L2(intersection_2geom - this->getPoint()) : Geom::L2(intersection_2geom - line.getPoint());
-        Geom::Coord secondaryDist = use_this_as_primary ? Geom::L2(intersection_2geom - line.getPoint()) : Geom::L2(intersection_2geom - this->getPoint());
-        return SnappedPoint(intersection, Inkscape::SNAPSOURCE_UNDEFINED, Inkscape::SNAPTARGET_UNDEFINED, primaryDist, primarySL->getTolerance(), primarySL->getAlwaysSnap(), true, true,
+        Geom::Coord primaryDist = use_this_as_primary ? Geom::L2(inters_pt - this->getPoint()) : Geom::L2(inters_pt - line.getPoint());
+        Geom::Coord secondaryDist = use_this_as_primary ? Geom::L2(inters_pt - line.getPoint()) : Geom::L2(inters_pt - this->getPoint());
+        return SnappedPoint(inters_pt, Inkscape::SNAPSOURCE_UNDEFINED, Inkscape::SNAPTARGET_UNDEFINED, primaryDist, primarySL->getTolerance(), primarySL->getAlwaysSnap(), true, true,
                                           secondaryDist, secondarySL->getTolerance(), secondarySL->getAlwaysSnap());
         // The type of the snap target is yet undefined, as we cannot tell whether
         // we're snapping to grid or the guide lines; must be set by on a higher level
     }
 
     // No intersection
-    return SnappedPoint(intersection, SNAPSOURCE_UNDEFINED, SNAPTARGET_UNDEFINED, NR_HUGE, 0, false, false, false, NR_HUGE, 0, false);
+    return SnappedPoint(Geom::Point(NR_HUGE, NR_HUGE), SNAPSOURCE_UNDEFINED, SNAPTARGET_UNDEFINED, NR_HUGE, 0, false, false, false, NR_HUGE, 0, false);
 }
 
 // search for the closest snapped line segment
index 85bbf1caa58b283057a1c90244fcae585ede9be6..3dec432e7eff4e119a01f1695f6be1d41bdf152b 100644 (file)
@@ -26,6 +26,7 @@ public:
     SnappedLineSegment(Geom::Point const &snapped_point, Geom::Coord const &snapped_distance, SnapSourceType const &source, SnapTargetType const &target, Geom::Coord const &snapped_tolerance,bool const &always_snap, Geom::Point const &start_point_of_line, Geom::Point const &end_point_of_line);
     ~SnappedLineSegment();
     Inkscape::SnappedPoint intersect(SnappedLineSegment const &line) const; //intersect with another SnappedLineSegment
+    Geom::LineSegment getLineSegment() const {return Geom::LineSegment(_start_point_of_line, _end_point_of_line);}
 
 private:
     Geom::Point _start_point_of_line;
@@ -46,6 +47,7 @@ public:
     Geom::Point getNormal() const {return _normal_to_line;}                             // n = (nx, ny)
     Geom::Point getPointOnLine() const {return _point_on_line;}                         // p = (px, py)
     Geom::Coord getConstTerm() const {return dot(_normal_to_line, _point_on_line);}     // c = n.p = nx*px + ny*py;
+    Geom::Line getLine() const {return Geom::Line(_point_on_line, _point_on_line + Geom::rot90(_normal_to_line));}
 
 private:
     Geom::Point _normal_to_line;