summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJohan B. C. Engelen <jbc.engelen@swissonline.ch>2008-07-23 19:56:43 +0000
committerjohanengelen <johanengelen@users.sourceforge.net>2008-07-23 19:56:43 +0000
commit3d16de46d5b95e2d8d105e3da9f11f886f0c4491 (patch)
tree126910f4f4ed7506a049c06d27856ea30c321815 /src
parent2geom path to livarot path conversion: don't add closing line segment when it... (diff)
downloadinkscape-3d16de46d5b95e2d8d105e3da9f11f886f0c4491.tar.gz
inkscape-3d16de46d5b95e2d8d105e3da9f11f886f0c4491.zip
fix nodetype determination. more stable now. (lost symmetry detection, nobody is using it yet). fixes lpe-spiro.
(bzr r6405)
Diffstat (limited to 'src')
-rw-r--r--src/helper/geom-nodetype.cpp55
1 files changed, 13 insertions, 42 deletions
diff --git a/src/helper/geom-nodetype.cpp b/src/helper/geom-nodetype.cpp
index 4bd5d4643..54c4e4e88 100644
--- a/src/helper/geom-nodetype.cpp
+++ b/src/helper/geom-nodetype.cpp
@@ -20,62 +20,33 @@
namespace Geom {
/*
+ * NOTE: THIS METHOD NEVER RETURNS "NODE_SYMM".
* Returns the nodetype between c_incoming and c_outgoing. Location of the node is
* at c_incoming.pointAt(1) == c_outgoing.pointAt(0). If these two are unequal,
* the returned type is NODE_NONE.
- * If one of the curves has zero length, but the other doesn't, then the returned type
- * is NODE_SMOOTH. If both have zero length, the returned type is NODE_SYMM. There is no
- * good reason for this. Feel free to change, but check all uses of this method such
- * that it doesn't break anything!
- * This method uses exact floating point comparison, so the final and initial points of
- * the two input curves should match exactly!
+ * Comparison is based on the unitTangent, does not work for NODE_SYMM!
*/
NodeType get_nodetype(Curve const &c_incoming, Curve const &c_outgoing)
{
- // FIXME: this should be exact floating point match, not are_near!
if ( !are_near(c_incoming.pointAt(1), c_outgoing.pointAt(0)) )
return NODE_NONE;
- Curve * c1_reverse = c_incoming.reverse();
- std::vector<Point> deriv1 = c1_reverse->pointAndDerivatives(0, 3);
- delete c1_reverse;
- std::vector<Point> deriv2 = c_outgoing.pointAndDerivatives(0, 3);
-
- // Determine lowest derivative that is non-zero
- int n1 = 1;
- while ( (deriv1[n1] == Point(0.,0.)) && (n1 <= 3) ) {
- n1++;
- }
- int n2 = 1;
- while ( (deriv2[n2] == Point(0.,0.)) && (n2 <= 3) ) {
- n2++;
- }
-
- // if one of the paths still has zero derivative
- if ( (n1 > 3) || (n2 > 3) ) {
- if (n1 == n2)
- return NODE_SYMM;
- else
- return NODE_SMOOTH;
- }
-
- // get unit derivatives, so the errors do not depend on absolute lengths of derivatives
- Geom::Point const d1 = - deriv1[n1] / deriv1[n1].length(); // reverse sign because it is taken in "wrong direction"
- Geom::Point const d2 = deriv2[n2] / deriv2[n2].length();
-
- double crossproduct = Geom::cross(d1, d2);
- if ( are_near( crossproduct , 0.) && (Geom::dot(d1, d2) > 0.) ) {
- // Apparently, the derivatives are colinear and in same direction but do they match exactly?
- if ( (n1 == n2) && (Geom::are_near(-deriv1[n1], deriv2[n2])) )
- return NODE_SYMM;
- else
- return NODE_SMOOTH;
+ Geom::Point deriv_1 = c_incoming.unitTangentAt(1);
+ Geom::Point deriv_2 = c_outgoing.unitTangentAt(0);
+ double this_angle_L2 = Geom::L2(deriv_1);
+ double next_angle_L2 = Geom::L2(deriv_2);
+ double both_angles_L2 = Geom::L2(deriv_1 + deriv_2);
+ if ( (this_angle_L2 > 1e-6) &&
+ (next_angle_L2 > 1e-6) &&
+ ((this_angle_L2 + next_angle_L2 - both_angles_L2) < 1e-3) )
+ {
+ return NODE_SMOOTH;
}
return NODE_CUSP;
}
-}
+} // end namespace Geom
/*
Local Variables: