GCC Code Coverage Report


Directory: ./
File: include/2geom/d2.h
Date: 2024-03-18 17:01:34
Exec Total Coverage
Lines: 56 176 31.8%
Functions: 32 74 43.2%
Branches: 63 303 20.8%

Line Branch Exec Source
1 /**
2 * \file
3 * \brief Lifts one dimensional objects into 2D
4 *//*
5 * Authors:
6 * Michael Sloan <mgsloan@gmail.com>
7 * Krzysztof KosiƄski <tweenk.pl@gmail.com>
8 *
9 * Copyright 2007-2015 Authors
10 *
11 * This library is free software; you can redistribute it and/or
12 * modify it either under the terms of the GNU Lesser General Public
13 * License version 2.1 as published by the Free Software Foundation
14 * (the "LGPL") or, at your option, under the terms of the Mozilla
15 * Public License Version 1.1 (the "MPL"). If you do not alter this
16 * notice, a recipient may use your version of this file under either
17 * the MPL or the LGPL.
18 *
19 * You should have received a copy of the LGPL along with this library
20 * in the file COPYING-LGPL-2.1; if not, output to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 * You should have received a copy of the MPL along with this library
23 * in the file COPYING-MPL-1.1
24 *
25 * The contents of this file are subject to the Mozilla Public License
26 * Version 1.1 (the "License"); you may not use this file except in
27 * compliance with the License. You may obtain a copy of the License at
28 * http://www.mozilla.org/MPL/
29 *
30 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
31 * OF ANY KIND, either express or implied. See the LGPL or the MPL for
32 * the specific language governing rights and limitations.
33 *
34 */
35
36 #ifndef LIB2GEOM_SEEN_D2_H
37 #define LIB2GEOM_SEEN_D2_H
38
39 #include <iterator>
40 #include <boost/concept/assert.hpp>
41 #include <boost/iterator/transform_iterator.hpp>
42 #include <2geom/point.h>
43 #include <2geom/interval.h>
44 #include <2geom/affine.h>
45 #include <2geom/rect.h>
46 #include <2geom/concepts.h>
47
48 namespace Geom {
49 /**
50 * @brief Adaptor that creates 2D functions from 1D ones.
51 * @ingroup Fragments
52 */
53 template <typename T>
54 class D2
55 {
56 private:
57 T f[2];
58
59 public:
60 typedef T D1Value;
61 typedef T &D1Reference;
62 typedef T const &D1ConstReference;
63
64
9/22
✓ Branch 1 taken 2367972 times.
✓ Branch 2 taken 1129963 times.
✓ Branch 3 taken 108046 times.
✓ Branch 4 taken 54023 times.
✓ Branch 6 taken 1129663 times.
✓ Branch 7 taken 54323 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 1129663 times.
✓ Branch 10 taken 54023 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 54023 times.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
3716241 D2() {f[X] = f[Y] = T();}
65 explicit D2(Point const &a) {
66 f[X] = T(a[X]); f[Y] = T(a[Y]);
67 }
68
69
4/10
✓ Branch 1 taken 587832 times.
✓ Branch 2 taken 164700 times.
✓ Branch 3 taken 258432 times.
✓ Branch 4 taken 129216 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
1763496 D2(T const &a, T const &b) {
70
1/2
✓ Branch 1 taken 293916 times.
✗ Branch 2 not taken.
587832 f[X] = a;
71
1/2
✓ Branch 1 taken 293916 times.
✗ Branch 2 not taken.
587832 f[Y] = b;
72
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
587832 }
73
74 template <typename Iter>
75 D2(Iter first, Iter last) {
76 typedef typename std::iterator_traits<Iter>::value_type V;
77 typedef typename boost::transform_iterator<GetAxis<X,V>, Iter> XIter;
78 typedef typename boost::transform_iterator<GetAxis<Y,V>, Iter> YIter;
79
80 XIter xfirst(first, GetAxis<X,V>()), xlast(last, GetAxis<X,V>());
81 f[X] = T(xfirst, xlast);
82 YIter yfirst(first, GetAxis<Y,V>()), ylast(last, GetAxis<Y,V>());
83 f[Y] = T(yfirst, ylast);
84 }
85
86 D2(std::vector<Point> const &vec) {
87 typedef Point V;
88 typedef std::vector<Point>::const_iterator Iter;
89 typedef boost::transform_iterator<GetAxis<X,V>, Iter> XIter;
90 typedef boost::transform_iterator<GetAxis<Y,V>, Iter> YIter;
91
92 XIter xfirst(vec.begin(), GetAxis<X,V>()), xlast(vec.end(), GetAxis<X,V>());
93 f[X] = T(xfirst, xlast);
94 YIter yfirst(vec.begin(), GetAxis<Y,V>()), ylast(vec.end(), GetAxis<Y,V>());
95 f[Y] = T(yfirst, ylast);
96 }
97
98 //TODO: ask MenTaLguY about operator= as seen in Point
99
100 11995128 T& operator[](unsigned i) { return f[i]; }
101 12942859 T const & operator[](unsigned i) const { return f[i]; }
102 46 Point point(unsigned i) const {
103 46 Point ret(f[X][i], f[Y][i]);
104 46 return ret;
105 }
106
107 //IMPL: FragmentConcept
108 typedef Point output_type;
109 bool isZero(double eps=EPSILON) const {
110 BOOST_CONCEPT_ASSERT((FragmentConcept<T>));
111 return f[X].isZero(eps) && f[Y].isZero(eps);
112 }
113 46 bool isConstant(double eps=EPSILON) const {
114 BOOST_CONCEPT_ASSERT((FragmentConcept<T>));
115
1/4
✗ Branch 1 not taken.
✓ Branch 2 taken 23 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
46 return f[X].isConstant(eps) && f[Y].isConstant(eps);
116 }
117 bool isFinite() const {
118 BOOST_CONCEPT_ASSERT((FragmentConcept<T>));
119 return f[X].isFinite() && f[Y].isFinite();
120 }
121 1013961 Point at0() const {
122 BOOST_CONCEPT_ASSERT((FragmentConcept<T>));
123 1013961 return Point(f[X].at0(), f[Y].at0());
124 }
125 631548 Point at1() const {
126 BOOST_CONCEPT_ASSERT((FragmentConcept<T>));
127
2/4
✓ Branch 2 taken 619974 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 619974 times.
✗ Branch 6 not taken.
631548 return Point(f[X].at1(), f[Y].at1());
128 }
129 Point pointAt(double t) const {
130 BOOST_CONCEPT_ASSERT((FragmentConcept<T>));
131 return (*this)(t);
132 }
133 38 Point valueAt(double t) const {
134 // TODO: remove this alias
135 BOOST_CONCEPT_ASSERT((FragmentConcept<T>));
136 38 return (*this)(t);
137 }
138 std::vector<Point > valueAndDerivatives(double t, unsigned n) const {
139 BOOST_CONCEPT_ASSERT((FragmentConcept<T>));
140 std::vector<Coord> x = f[X].valueAndDerivatives(t, n),
141 y = f[Y].valueAndDerivatives(t, n); // always returns a vector of size n+1
142 std::vector<Point> res(n+1);
143 for(unsigned i = 0; i <= n; i++) {
144 res[i] = Point(x[i], y[i]);
145 }
146 return res;
147 }
148 216 D2<SBasis> toSBasis() const {
149 BOOST_CONCEPT_ASSERT((FragmentConcept<T>));
150
3/6
✓ Branch 2 taken 216 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 216 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 216 times.
✗ Branch 10 not taken.
216 return D2<SBasis>(f[X].toSBasis(), f[Y].toSBasis());
151 }
152
153 Point operator()(double t) const;
154 Point operator()(double x, double y) const;
155 };
156 template <typename T>
157 164700 inline D2<T> reverse(const D2<T> &a) {
158 BOOST_CONCEPT_ASSERT((FragmentConcept<T>));
159
3/6
✓ Branch 3 taken 164700 times.
✗ Branch 4 not taken.
✓ Branch 8 taken 164700 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 164700 times.
✗ Branch 12 not taken.
164700 return D2<T>(reverse(a[X]), reverse(a[Y]));
160 }
161
162 template <typename T>
163 inline D2<T> portion(const D2<T> &a, Coord f, Coord t) {
164 BOOST_CONCEPT_ASSERT((FragmentConcept<T>));
165 return D2<T>(portion(a[X], f, t), portion(a[Y], f, t));
166 }
167
168 template <typename T>
169 inline D2<T> portion(const D2<T> &a, Interval i) {
170 BOOST_CONCEPT_ASSERT((FragmentConcept<T>));
171 return D2<T>(portion(a[X], i), portion(a[Y], i));
172 }
173
174 //IMPL: EqualityComparableConcept
175 template <typename T>
176 inline bool
177 operator==(D2<T> const &a, D2<T> const &b) {
178 BOOST_CONCEPT_ASSERT((EqualityComparableConcept<T>));
179 return a[0]==b[0] && a[1]==b[1];
180 }
181 template <typename T>
182 inline bool
183 operator!=(D2<T> const &a, D2<T> const &b) {
184 BOOST_CONCEPT_ASSERT((EqualityComparableConcept<T>));
185 return a[0]!=b[0] || a[1]!=b[1];
186 }
187
188 //IMPL: NearConcept
189 template <typename T>
190 inline bool
191 are_near(D2<T> const &a, D2<T> const &b, double tol) {
192 BOOST_CONCEPT_ASSERT((NearConcept<T>));
193 return are_near(a[0], b[0], tol) && are_near(a[1], b[1], tol);
194 }
195
196 //IMPL: AddableConcept
197 template <typename T>
198 inline D2<T>
199 21000 operator+(D2<T> const &a, D2<T> const &b) {
200 BOOST_CONCEPT_ASSERT((AddableConcept<T>));
201
202 21000 D2<T> r;
203
2/2
✓ Branch 0 taken 42000 times.
✓ Branch 1 taken 21000 times.
63000 for(unsigned i = 0; i < 2; i++)
204
2/4
✓ Branch 4 taken 42000 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 42000 times.
✗ Branch 9 not taken.
42000 r[i] = a[i] + b[i];
205 21000 return r;
206 }
207 template <typename T>
208 inline D2<T>
209 operator-(D2<T> const &a, D2<T> const &b) {
210 BOOST_CONCEPT_ASSERT((AddableConcept<T>));
211
212 D2<T> r;
213 for(unsigned i = 0; i < 2; i++)
214 r[i] = a[i] - b[i];
215 return r;
216 }
217 template <typename T>
218 inline D2<T>
219 operator+=(D2<T> &a, D2<T> const &b) {
220 BOOST_CONCEPT_ASSERT((AddableConcept<T>));
221
222 for(unsigned i = 0; i < 2; i++)
223 a[i] += b[i];
224 return a;
225 }
226 template <typename T>
227 inline D2<T>
228 operator-=(D2<T> &a, D2<T> const & b) {
229 BOOST_CONCEPT_ASSERT((AddableConcept<T>));
230
231 for(unsigned i = 0; i < 2; i++)
232 a[i] -= b[i];
233 return a;
234 }
235
236 //IMPL: ScalableConcept
237 template <typename T>
238 inline D2<T>
239 operator-(D2<T> const & a) {
240 BOOST_CONCEPT_ASSERT((ScalableConcept<T>));
241 D2<T> r;
242 for(unsigned i = 0; i < 2; i++)
243 r[i] = -a[i];
244 return r;
245 }
246 template <typename T>
247 inline D2<T>
248 operator*(D2<T> const & a, Point const & b) {
249 BOOST_CONCEPT_ASSERT((ScalableConcept<T>));
250
251 D2<T> r;
252 for(unsigned i = 0; i < 2; i++)
253 r[i] = a[i] * b[i];
254 return r;
255 }
256 template <typename T>
257 inline D2<T>
258 operator/(D2<T> const & a, Point const & b) {
259 BOOST_CONCEPT_ASSERT((ScalableConcept<T>));
260 //TODO: b==0?
261 D2<T> r;
262 for(unsigned i = 0; i < 2; i++)
263 r[i] = a[i] / b[i];
264 return r;
265 }
266 template <typename T>
267 inline D2<T>
268 operator*=(D2<T> &a, Point const & b) {
269 BOOST_CONCEPT_ASSERT((ScalableConcept<T>));
270
271 for(unsigned i = 0; i < 2; i++)
272 a[i] *= b[i];
273 return a;
274 }
275 template <typename T>
276 inline D2<T>
277 operator/=(D2<T> &a, Point const & b) {
278 BOOST_CONCEPT_ASSERT((ScalableConcept<T>));
279 //TODO: b==0?
280 for(unsigned i = 0; i < 2; i++)
281 a[i] /= b[i];
282 return a;
283 }
284
285 template <typename T>
286 inline D2<T> operator*(D2<T> const & a, double b) { return D2<T>(a[0]*b, a[1]*b); }
287 template <typename T>
288 inline D2<T> operator*=(D2<T> & a, double b) { a[0] *= b; a[1] *= b; return a; }
289 template <typename T>
290
3/6
✓ Branch 3 taken 21300 times.
✗ Branch 4 not taken.
✓ Branch 8 taken 21300 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 21300 times.
✗ Branch 12 not taken.
21300 inline D2<T> operator/(D2<T> const & a, double b) { return D2<T>(a[0]/b, a[1]/b); }
291 template <typename T>
292 inline D2<T> operator/=(D2<T> & a, double b) { a[0] /= b; a[1] /= b; return a; }
293
294 template<typename T>
295 20024 D2<T> operator*(D2<T> const &v, Affine const &m) {
296 BOOST_CONCEPT_ASSERT((AddableConcept<T>));
297 BOOST_CONCEPT_ASSERT((ScalableConcept<T>));
298 20024 D2<T> ret;
299
2/2
✓ Branch 0 taken 40048 times.
✓ Branch 1 taken 20024 times.
60072 for(unsigned i = 0; i < 2; i++)
300
5/15
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 40048 times.
✗ Branch 10 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 16 taken 40048 times.
✗ Branch 17 not taken.
✓ Branch 19 taken 40048 times.
✗ Branch 20 not taken.
✓ Branch 22 taken 40048 times.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✓ Branch 26 taken 40048 times.
✗ Branch 27 not taken.
40048 ret[i] = v[X] * m[i] + v[Y] * m[i + 2] + m[i + 4];
301 20024 return ret;
302 }
303
304 //IMPL: MultiplicableConcept
305 template <typename T>
306 inline D2<T>
307 operator*(D2<T> const & a, T const & b) {
308 BOOST_CONCEPT_ASSERT((MultiplicableConcept<T>));
309 D2<T> ret;
310 for(unsigned i = 0; i < 2; i++)
311 ret[i] = a[i] * b;
312 return ret;
313 }
314
315 //IMPL:
316
317 //IMPL: OffsetableConcept
318 template <typename T>
319 inline D2<T>
320 operator+(D2<T> const & a, Point b) {
321 BOOST_CONCEPT_ASSERT((OffsetableConcept<T>));
322 D2<T> r;
323 for(unsigned i = 0; i < 2; i++)
324 r[i] = a[i] + b[i];
325 return r;
326 }
327 template <typename T>
328 inline D2<T>
329 46 operator-(D2<T> const & a, Point b) {
330 BOOST_CONCEPT_ASSERT((OffsetableConcept<T>));
331 46 D2<T> r;
332
2/2
✓ Branch 0 taken 46 times.
✓ Branch 1 taken 23 times.
138 for(unsigned i = 0; i < 2; i++)
333
2/4
✓ Branch 4 taken 46 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 46 times.
✗ Branch 9 not taken.
92 r[i] = a[i] - b[i];
334 46 return r;
335 }
336 template <typename T>
337 inline D2<T>
338 operator+=(D2<T> & a, Point b) {
339 BOOST_CONCEPT_ASSERT((OffsetableConcept<T>));
340 for(unsigned i = 0; i < 2; i++)
341 a[i] += b[i];
342 return a;
343 }
344 template <typename T>
345 inline D2<T>
346 operator-=(D2<T> & a, Point b) {
347 BOOST_CONCEPT_ASSERT((OffsetableConcept<T>));
348 for(unsigned i = 0; i < 2; i++)
349 a[i] -= b[i];
350 return a;
351 }
352
353 template <typename T>
354 inline T
355 9666 dot(D2<T> const & a, D2<T> const & b) {
356 BOOST_CONCEPT_ASSERT((AddableConcept<T>));
357 BOOST_CONCEPT_ASSERT((MultiplicableConcept<T>));
358
359 9666 T r;
360
2/2
✓ Branch 0 taken 19332 times.
✓ Branch 1 taken 9666 times.
28998 for(unsigned i = 0; i < 2; i++)
361
2/4
✓ Branch 4 taken 19332 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 19332 times.
✗ Branch 8 not taken.
19332 r += a[i] * b[i];
362 9666 return r;
363 }
364
365 /** @brief Calculates the 'dot product' or 'inner product' of \c a and \c b
366 * @return \f$a \bullet b = a_X b_X + a_Y b_Y\f$.
367 * @relates D2 */
368 template <typename T>
369 inline T
370 dot(D2<T> const & a, Point const & b) {
371 BOOST_CONCEPT_ASSERT((AddableConcept<T>));
372 BOOST_CONCEPT_ASSERT((ScalableConcept<T>));
373
374 T r;
375 for(unsigned i = 0; i < 2; i++) {
376 r += a[i] * b[i];
377 }
378 return r;
379 }
380
381 /** @brief Calculates the 'cross product' or 'outer product' of \c a and \c b
382 * @return \f$a \times b = a_Y b_X - a_X b_Y\f$.
383 * @relates D2 */
384 template <typename T>
385 inline T
386 cross(D2<T> const & a, D2<T> const & b) {
387 BOOST_CONCEPT_ASSERT((ScalableConcept<T>));
388 BOOST_CONCEPT_ASSERT((MultiplicableConcept<T>));
389
390 return a[1] * b[0] - a[0] * b[1];
391 }
392
393
394 //equivalent to cw/ccw, for use in situations where rotation direction doesn't matter.
395 template <typename T>
396 inline D2<T>
397 11766 rot90(D2<T> const & a) {
398 BOOST_CONCEPT_ASSERT((ScalableConcept<T>));
399
2/4
✓ Branch 4 taken 11766 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 11766 times.
✗ Branch 8 not taken.
11766 return D2<T>(-a[Y], a[X]);
400 }
401
402 //TODO: concepterize the following functions
403 template <typename T>
404 inline D2<T>
405 compose(D2<T> const & a, T const & b) {
406 D2<T> r;
407 for(unsigned i = 0; i < 2; i++)
408 r[i] = compose(a[i],b);
409 return r;
410 }
411
412 template <typename T>
413 inline D2<T>
414 compose_each(D2<T> const & a, D2<T> const & b) {
415 D2<T> r;
416 for(unsigned i = 0; i < 2; i++)
417 r[i] = compose(a[i],b[i]);
418 return r;
419 }
420
421 template <typename T>
422 inline D2<T>
423 compose_each(T const & a, D2<T> const & b) {
424 D2<T> r;
425 for(unsigned i = 0; i < 2; i++)
426 r[i] = compose(a,b[i]);
427 return r;
428 }
429
430
431 template<typename T>
432 inline Point
433 D2<T>::operator()(double t) const {
434 Point p;
435 for(unsigned i = 0; i < 2; i++)
436 p[i] = (*this)[i](t);
437 return p;
438 }
439
440 //TODO: we might want to have this take a Point as the parameter.
441 template<typename T>
442 inline Point
443 D2<T>::operator()(double x, double y) const {
444 Point p;
445 for(unsigned i = 0; i < 2; i++)
446 p[i] = (*this)[i](x, y);
447 return p;
448 }
449
450
451 template<typename T>
452 21412 D2<T> derivative(D2<T> const & a) {
453
3/6
✓ Branch 3 taken 21389 times.
✗ Branch 4 not taken.
✓ Branch 8 taken 21389 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 21389 times.
✗ Branch 12 not taken.
21412 return D2<T>(derivative(a[X]), derivative(a[Y]));
454 }
455 template<typename T>
456 66 D2<T> integral(D2<T> const & a) {
457
3/6
✓ Branch 3 taken 66 times.
✗ Branch 4 not taken.
✓ Branch 8 taken 66 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 66 times.
✗ Branch 12 not taken.
66 return D2<T>(integral(a[X]), integral(a[Y]));
458 }
459
460 /** A function to print out the Point. It just prints out the coords
461 on the given output stream */
462 template <typename T>
463 inline std::ostream &operator<< (std::ostream &out_file, const Geom::D2<T> &in_d2) {
464 out_file << "X: " << in_d2[X] << " Y: " << in_d2[Y];
465 return out_file;
466 }
467
468 //Some D2 Fragment implementation which requires rect:
469 template <typename T>
470 20000 OptRect bounds_fast(const D2<T> &a) {
471 BOOST_CONCEPT_ASSERT((FragmentConcept<T>));
472
3/6
✓ Branch 3 taken 20000 times.
✗ Branch 4 not taken.
✓ Branch 8 taken 20000 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 20000 times.
✗ Branch 12 not taken.
40000 return OptRect(bounds_fast(a[X]), bounds_fast(a[Y]));
473 }
474 template <typename T>
475 24000 OptRect bounds_exact(const D2<T> &a) {
476 BOOST_CONCEPT_ASSERT((FragmentConcept<T>));
477
3/6
✓ Branch 3 taken 12000 times.
✗ Branch 4 not taken.
✓ Branch 8 taken 12000 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 12000 times.
✗ Branch 12 not taken.
48000 return OptRect(bounds_exact(a[X]), bounds_exact(a[Y]));
478 }
479 template <typename T>
480 OptRect bounds_local(const D2<T> &a, const OptInterval &t) {
481 BOOST_CONCEPT_ASSERT((FragmentConcept<T>));
482 return OptRect(bounds_local(a[X], t), bounds_local(a[Y], t));
483 }
484
485
486
487 // SBasis-specific declarations
488
489 53700 inline D2<SBasis> compose(D2<SBasis> const & a, SBasis const & b) {
490
3/6
✓ Branch 3 taken 53700 times.
✗ Branch 4 not taken.
✓ Branch 8 taken 53700 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 53700 times.
✗ Branch 12 not taken.
107400 return D2<SBasis>(compose(a[X], b), compose(a[Y], b));
491 }
492
493 SBasis L2(D2<SBasis> const & a, unsigned k);
494 double L2(D2<double> const & a);
495
496 D2<SBasis> multiply(Linear const & a, D2<SBasis> const & b);
497 inline D2<SBasis> operator*(Linear const & a, D2<SBasis> const & b) { return multiply(a, b); }
498 D2<SBasis> multiply(SBasis const & a, D2<SBasis> const & b);
499 21000 inline D2<SBasis> operator*(SBasis const & a, D2<SBasis> const & b) { return multiply(a, b); }
500 D2<SBasis> truncate(D2<SBasis> const & a, unsigned terms);
501
502 unsigned sbasis_size(D2<SBasis> const & a);
503 double tail_error(D2<SBasis> const & a, unsigned tail);
504
505 //Piecewise<D2<SBasis> > specific declarations
506
507 Piecewise<D2<SBasis> > sectionize(D2<Piecewise<SBasis> > const &a);
508 D2<Piecewise<SBasis> > make_cuts_independent(Piecewise<D2<SBasis> > const &a);
509 Piecewise<D2<SBasis> > rot90(Piecewise<D2<SBasis> > const &a);
510 Piecewise<SBasis> dot(Piecewise<D2<SBasis> > const &a, Piecewise<D2<SBasis> > const &b);
511 Piecewise<SBasis> dot(Piecewise<D2<SBasis> > const &a, Point const &b);
512 Piecewise<SBasis> cross(Piecewise<D2<SBasis> > const &a, Piecewise<D2<SBasis> > const &b);
513
514 Piecewise<D2<SBasis> > operator*(Piecewise<D2<SBasis> > const &a, Affine const &m);
515
516 Piecewise<D2<SBasis> > force_continuity(Piecewise<D2<SBasis> > const &f, double tol=0, bool closed=false);
517
518 std::vector<Piecewise<D2<SBasis> > > fuse_nearby_ends(std::vector<Piecewise<D2<SBasis> > > const &f, double tol=0);
519
520 std::vector<Geom::Piecewise<Geom::D2<Geom::SBasis> > > split_at_discontinuities (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwsbin, double tol = .0001);
521
522 Point unitTangentAt(D2<SBasis> const & a, Coord t, unsigned n = 3);
523
524 //bounds specializations with order
525 inline OptRect bounds_fast(D2<SBasis> const & s, unsigned order=0) {
526 OptRect retval;
527 OptInterval xint = bounds_fast(s[X], order);
528 if (xint) {
529 OptInterval yint = bounds_fast(s[Y], order);
530 if (yint) {
531 retval = Rect(*xint, *yint);
532 }
533 }
534 return retval;
535 }
536 inline OptRect bounds_local(D2<SBasis> const & s, OptInterval i, unsigned order=0) {
537 OptRect retval;
538 OptInterval xint = bounds_local(s[X], i, order);
539 OptInterval yint = bounds_local(s[Y], i, order);
540 if (xint && yint) {
541 retval = Rect(*xint, *yint);
542 }
543 return retval;
544 }
545
546 std::vector<Interval> level_set( D2<SBasis> const &f, Rect region);
547 std::vector<Interval> level_set( D2<SBasis> const &f, Point p, double tol);
548 std::vector<std::vector<Interval> > level_sets( D2<SBasis> const &f, std::vector<Rect> regions);
549 std::vector<std::vector<Interval> > level_sets( D2<SBasis> const &f, std::vector<Point> pts, double tol);
550
551
552 } // end namespace Geom
553
554 #endif
555 /*
556 Local Variables:
557 mode:c++
558 c-file-style:"stroustrup"
559 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
560 indent-tabs-mode:nil
561 fill-column:99
562 End:
563 */
564 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
565