summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: f62b878)
raw | patch | inline | side by side (parent: f62b878)
author | johanengelen <johanengelen@users.sourceforge.net> | |
Wed, 23 Jul 2008 19:56:43 +0000 (19:56 +0000) | ||
committer | johanengelen <johanengelen@users.sourceforge.net> | |
Wed, 23 Jul 2008 19:56:43 +0000 (19:56 +0000) |
src/helper/geom-nodetype.cpp | patch | blob | history |
index 4bd5d4643d8ad83575ef19f913765113ee7a5023..54c4e4e889eba64b0bb9dc211e8e6e3d2c491da9 100644 (file)
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: