1 #define INKSCAPE_HELPER_GEOM_NODETYPE_CPP
3 /**
4 * Specific nodetype geometry functions for Inkscape, not provided my lib2geom.
5 *
6 * Author:
7 * Johan Engelen <goejendaagh@zonnet.nl>
8 *
9 * Copyright (C) 2008 Johan Engelen
10 *
11 * Released under GNU GPL
12 */
14 #include "helper/geom-nodetype.h"
16 #include <2geom/curve.h>
17 #include <2geom/point.h>
18 #include <vector>
20 namespace Geom {
22 /*
23 * Returns the nodetype between c_incoming and c_outgoing. Location of the node is
24 * at c_incoming.pointAt(1) == c_outgoing.pointAt(0). If these two are unequal,
25 * the returned type is NODE_NONE.
26 * If one of the curves has zero length, but the other doesn't, then the returned type
27 * is NODE_SMOOTH. If both have zero length, the returned type is NODE_SYMM. There is no
28 * good reason for this. Feel free to change, but check all uses of this method such
29 * that it doesn't break anything!
30 * This method uses exact floating point comparison, so the final and initial points of
31 * the two input curves should match exactly!
32 */
33 NodeType get_nodetype(Curve const &c_incoming, Curve const &c_outgoing)
34 {
35 // FIXME: this should be exact floating point match, not are_near!
36 if ( !are_near(c_incoming.pointAt(1), c_outgoing.pointAt(0)) )
37 return NODE_NONE;
39 Curve * c1_reverse = c_incoming.reverse();
40 std::vector<Point> deriv1 = c1_reverse->pointAndDerivatives(0, 3);
41 delete c1_reverse;
42 std::vector<Point> deriv2 = c_outgoing.pointAndDerivatives(0, 3);
44 // Determine lowest derivative that is non-zero
45 int n1 = 1;
46 while ( (deriv1[n1] == Point(0,0)) && (n1 <= 3) ) {
47 n1++;
48 }
49 int n2 = 1;
50 while ( (deriv2[n2] == Point(0,0)) && (n2 <= 3) ) {
51 n2++;
52 }
54 // if one of the paths still has zero derivative
55 if ( (n1 > 3) || (n2 > 3) ) {
56 if (n1 == n2)
57 return NODE_SYMM;
58 else
59 return NODE_SMOOTH;
60 }
62 double const angle1 = Geom::atan2(-deriv1[n1]);
63 double const angle2 = Geom::atan2(deriv2[n2]);
65 if ( !are_near(angle1, angle2) )
66 return NODE_CUSP; // derivatives are not colinear
68 // Apparently, the derivatives are colinear but does the order of the derivatives match?
69 if (n1 != n2)
70 return NODE_SMOOTH;
71 else
72 return NODE_SYMM;
73 }
75 }
77 /*
78 Local Variables:
79 mode:c++
80 c-file-style:"stroustrup"
81 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
82 indent-tabs-mode:nil
83 fill-column:99
84 End:
85 */
86 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :