Inkscape
Vector Graphics Editor
Loading...
Searching...
No Matches
geom-nodesatellite.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-or-later
/*
5 * Authors:
6 * see git history
7 * 2015 Jabier Arraiza Cenoz<jabier.arraiza@marker.es>
8 *
9 * Copyright (C) 2018 Authors
10 * Released under GNU GPL v2+, read the file 'COPYING' for more information.
11 */
12
13#include <2geom/curve.h>
14#include <2geom/nearest-time.h>
16#include <2geom/ray.h>
19#include <optional>
20// log cache
21#ifdef _WIN32
22#include <Windows.h>
23#else
24#include <sys/time.h>
25#include <ctime>
26#endif
27
30
32 : nodesatellite_type(nodesatellite_type)
33 , is_time(false)
34 , selected(false)
35 , has_mirror(false)
36 , hidden(true)
37 , amount(0.0)
38 , angle(0.0)
39 , steps(0)
40{}
41
43
45//TODO: find a better place to it
46double timeAtArcLength(double const A, Geom::Curve const &curve_in)
47{
48 if ( A == 0 || curve_in.isDegenerate()) {
49 return 0;
50 }
51
52 Geom::D2<Geom::SBasis> d2_in = curve_in.toSBasis();
53 double t = 0;
54 double length_part = curve_in.length();
55 if (A >= length_part || curve_in.isLineSegment()) {
56 if (length_part != 0) {
57 t = A / length_part;
58 }
59 } else if (!curve_in.isLineSegment()) {
60 std::vector<double> t_roots = roots(Geom::arcLengthSb(d2_in) - A);
61 if (!t_roots.empty()) {
62 t = t_roots[0];
63 }
64 }
65 return t;
66}
67
69//TODO: find a better place to it
70double arcLengthAt(double const A, Geom::Curve const &curve_in)
71{
72 if ( A == 0 || curve_in.isDegenerate()) {
73 return 0;
74 }
75
76 double s = 0;
77 double length_part = curve_in.length();
78 if (A > length_part || curve_in.isLineSegment()) {
79 s = (A * length_part);
80 } else if (!curve_in.isLineSegment()) {
81 Geom::Curve *curve = curve_in.portion(0.0, A);
82 s = curve->length();
83 delete curve;
84 }
85 return s;
86}
87
90double NodeSatellite::radToLen(double const A, Geom::Curve const &curve_in, Geom::Curve const &curve_out) const
91{
92 double len = 0;
93 Geom::D2<Geom::SBasis> d2_in = curve_in.toSBasis();
94 Geom::D2<Geom::SBasis> d2_out = curve_out.toSBasis();
97 rot90(unitVector(derivative(d2_in))) * (A);
100 rot90(unitVector(derivative(d2_out))) * (A);
101 offset_curve0[0][0].normalize();
102 offset_curve0[0][1].normalize();
103 Geom::Path p0 = path_from_piecewise(offset_curve0, 0.1)[0];
104 offset_curve1[0][0].normalize();
105 offset_curve1[0][1].normalize();
106 Geom::Path p1 = path_from_piecewise(offset_curve1, 0.1)[0];
107 Geom::Crossings cs = Geom::crossings(p0, p1);
108 if (cs.size() > 0) {
109 Geom::Point cp = p0(cs[0].ta);
110 double p0pt = nearest_time(cp, curve_out);
111 len = arcLengthAt(p0pt, curve_out);
112 } else {
113 if (A > 0) {
114 len = radToLen(A * -1, curve_in, curve_out);
115 }
116 }
117 return len;
118}
119
122double NodeSatellite::lenToRad(double const A, Geom::Curve const &curve_in, Geom::Curve const &curve_out,
123 NodeSatellite const previousNodeSatellite) const
124{
125 double time_in = (previousNodeSatellite).time(A, true, curve_in);
126 double time_out = timeAtArcLength(A, curve_out);
127 Geom::Point start_arc_point = curve_in.pointAt(time_in);
128 Geom::Point end_arc_point = curve_out.pointAt(time_out);
129 Geom::Curve *knot_curve1 = curve_in.portion(0, time_in);
130 Geom::Curve *knot_curve2 = curve_out.portion(time_out, 1);
131 Geom::CubicBezier const *cubic1 = dynamic_cast<Geom::CubicBezier const *>(&*knot_curve1);
132 Geom::Ray ray1(start_arc_point, curve_in.pointAt(1));
133 if (cubic1) {
134 ray1.setPoints((*cubic1)[2], start_arc_point);
135 }
136 Geom::CubicBezier const *cubic2 = dynamic_cast<Geom::CubicBezier const *>(&*knot_curve2);
137 Geom::Ray ray2(curve_out.pointAt(0), end_arc_point);
138 if (cubic2) {
139 ray2.setPoints(end_arc_point, (*cubic2)[1]);
140 }
141 bool ccw_toggle = cross(curve_in.pointAt(1) - start_arc_point,
142 end_arc_point - start_arc_point) < 0;
143 double distance_arc =
144 Geom::distance(start_arc_point, middle_point(start_arc_point, end_arc_point));
145 double angle = angle_between(ray1, ray2, ccw_toggle);
146 double divisor = std::sin(angle / 2.0);
147 if (divisor > 0) {
148 return distance_arc / divisor;
149 }
150 return 0;
151}
152
154double NodeSatellite::time(Geom::Curve const &curve_in, bool inverse) const
155{
156 double t = amount;
157 if (!is_time) {
158 t = time(t, inverse, curve_in);
159 } else if (inverse) {
160 t = 1-t;
161 }
162 if (t > 1) {
163 t = 1;
164 }
165 return t;
166}
167
169double NodeSatellite::time(double A, bool inverse, Geom::Curve const &curve_in) const
170{
171 if (A == 0 && inverse) {
172 return 1;
173 }
174 if (A == 0 && !inverse) {
175 return 0;
176 }
177 if (!inverse) {
178 return timeAtArcLength(A, curve_in);
179 }
180 double length_part = curve_in.length();
181 A = length_part - A;
182 return timeAtArcLength(A, curve_in);
183}
184
186double NodeSatellite::arcDistance(Geom::Curve const &curve_in) const
187{
188 double s = amount;
189 if (is_time) {
190 s = arcLengthAt(s, curve_in);
191 }
192 return s;
193}
194
196Geom::Point NodeSatellite::getPosition(Geom::Curve const &curve_in, bool inverse) const
197{
198 double t = time(curve_in, inverse);
199 return curve_in.pointAt(t);
200}
201
203void NodeSatellite::setPosition(Geom::Point const p, Geom::Curve const &curve_in, bool inverse)
204{
205 Geom::Curve * curve = const_cast<Geom::Curve *>(&curve_in);
206 if (inverse) {
207 curve = curve->reverse();
208 }
209 double A = Geom::nearest_time(p, *curve);
210 if (!is_time) {
211 A = arcLengthAt(A, *curve);
212 }
213 amount = A;
214}
215
218{
219 std::map<std::string, NodeSatelliteType> gchar_map_to_nodesatellite_type = boost::assign::map_list_of("F", FILLET)(
220 "IF", INVERSE_FILLET)("C", CHAMFER)("IC", INVERSE_CHAMFER)("KO", INVALID_SATELLITE);
221 auto it = gchar_map_to_nodesatellite_type.find(std::string(A));
222 if (it != gchar_map_to_nodesatellite_type.end()) {
223 nodesatellite_type = it->second;
224 }
225}
226
229{
230 std::map<NodeSatelliteType, gchar const *> nodesatellite_type_to_gchar_map = boost::assign::map_list_of(
231 FILLET, "F")(INVERSE_FILLET, "IF")(CHAMFER, "C")(INVERSE_CHAMFER, "IC")(INVALID_SATELLITE, "KO");
232 return nodesatellite_type_to_gchar_map.at(nodesatellite_type);
233}
234
235/*
236 Local Variables:
237 mode:c++
238 c-file-style:"stroustrup"
239 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
240 indent-tabs-mode:nil
241 fill-column:99
242 End:
243*/
244// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
Abstract curve type.
Bezier curve with compile-time specified order.
Abstract continuous curve on a plane defined on [0,1].
Definition curve.h:78
virtual D2< SBasis > toSBasis() const =0
Convert the curve to a symmetric power basis polynomial.
virtual bool isDegenerate() const =0
Check whether the curve has exactly zero length.
virtual Coord length(Coord tolerance=0.01) const
Compute the arc length of this curve.
Definition curve.cpp:56
virtual Curve * portion(Coord a, Coord b) const =0
Create a curve that corresponds to a part of this curve.
virtual bool isLineSegment() const
Check whether the curve is a line segment.
Definition curve.h:98
virtual Point pointAt(Coord t) const
Evaluate the curve at a specified time value.
Definition curve.h:110
Adaptor that creates 2D functions from 1D ones.
Definition d2.h:55
Sequence of contiguous curves, aka spline.
Definition path.h:353
Function defined as discrete pieces.
Definition piecewise.h:71
Two-dimensional point that doubles as a vector.
Definition point.h:66
Straight ray from a specific point to infinity.
Definition ray.h:53
void setPoints(Point const &a, Point const &b)
Definition ray.h:75
NodeSatellite a per node holder of data.
NodeSatelliteType nodesatellite_type
NodeSatellite()
NodeSatellite a per node holder of data.
double lenToRad(double const A, Geom::Curve const &curve_in, Geom::Curve const &curve_out, NodeSatellite const previousNodeSatellite) const
Convert a nodesatellite length -point position where fillet/chamfer knot be on original curve- to a a...
gchar const * getNodeSatellitesTypeGchar() const
Map a gchar with nodesatelliteType.
void setNodeSatellitesType(gchar const *A)
Map a nodesatellite type with gchar.
Geom::Point getPosition(Geom::Curve const &curve_in, bool inverse=false) const
Get the point position of the nodesatellite.
double arcDistance(Geom::Curve const &curve_in) const
Get the length of the nodesatellite in curve_in.
double time(Geom::Curve const &curve_in, bool inverse=false) const
Get the time position of the nodesatellite in curve_in.
void setPosition(Geom::Point const p, Geom::Curve const &curve_in, bool inverse=false)
Set the position of the nodesatellite from a given point P.
virtual ~NodeSatellite()
double radToLen(double const A, Geom::Curve const &curve_in, Geom::Curve const &curve_out) const
Convert a arc radius of a fillet/chamfer to his nodesatellite length -point position where fillet/cha...
double timeAtArcLength(double const A, Geom::Curve const &curve_in)
Calculate the time in curve_in with a size of A.
double arcLengthAt(double const A, Geom::Curve const &curve_in)
Calculate the size in curve_in with a point at A.
NodeSatellite – a per node holder of data.
NodeSatelliteType
@ INVERSE_FILLET
@ INVERSE_CHAMFER
@ CHAMFER
@ INVALID_SATELLITE
double timeAtArcLength(double const A, Geom::Curve const &curve_in)
Calculate the time in curve_in with a size of A.
double arcLengthAt(double const A, Geom::Curve const &curve_in)
Calculate the size in curve_in with a point at A.
Coord nearest_time(Point const &p, Curve const &c)
Definition curve.h:354
Angle distance(Angle const &a, Angle const &b)
Definition angle.h:163
std::vector< Crossing > Crossings
Definition crossing.h:126
Crossings crossings(Curve const &a, Curve const &b)
Piecewise< SBasis > arcLengthSb(D2< SBasis > const &M, double tol=.01)
Nearest time routines for D2<SBasis> and Piecewise<D2<SBasis>>
Path intersection.
Infinite straight ray.
auto len
Definition safe-printf.h:21
Conversion between SBasis and Bezier basis polynomials.
Definition curve.h:24
unsigned length
Definition curve.h:26