1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
/*
* Test performance of bezier-util fitting code
*
* Copyright (C) authors 2013
* Authors:
* Johan Engelen <j.b.c.engelen@alumnus.utwente.nl>
*
* Released under GNU GPL, read the file 'COPYING' for more information
*/
#include <iostream>
#include <ctime>
#include "2geom/bezier-utils.h"
#include "2geom/path.h"
using namespace Geom;
//static const Point data[] = { Point(0, 0), Point(1, 0), Point( 2, 0 ), Point( 1, 1 )};
static const Point data[] = { Point( 0, 0 ), Point( 1, 0 ), Point( 2, 0 ), Point( 1, 1 ),
Point( 1, 2 ), Point( 1, 3 ), Point( 3, 0 ), Point( 4, 0 ),
Point( 2, 0 ), Point( 1, 1 ), Point( 1, 2 ), Point( 2, 0 ),
Point( 1, 0 ), Point( 2, 0 ), Point( 1, 3 ), Point( 1, 4 ),
Point( 1, 2 ), Point( 1, 1 ), Point( 0, 0 ), Point( 1, 0 ),
Point( 2, 0 ), Point( 1, 1 ), Point( 1, 2 ), Point( 1, 3 ),
Point( 4, 0 ), Point( 2, 0 ), Point( 1, 1 ), Point( 1, 2 ),
Point( 2, 0 ), Point( 1, 0 ), Point( 2, 0 ), Point( 1, 3 ),
Point( 1, 4 ), Point( 1, 2 ), Point( 1, 1 ), Point( 2, 1 ) };
static const unsigned int data_len = sizeof(data)/sizeof(Point);
// code test with 2geom types
Path interpolateToPath(std::vector<Point> const &points, double tolerance_sq, unsigned max_beziers)
{
Geom::Point *b = new Geom::Point[max_beziers*4];
Geom::Point *points_array = new Geom::Point[4 * points.size()]; // for safety, do a copy into a vector. I think it
// is possible to simply pass &points[0] as a
// Point[], but I am not sure
for (size_t i = 0; i < points.size(); ++i) {
points_array[i] = points.at(i);
}
int const n_segs = Geom::bezier_fit_cubic_r(b, points_array, points.size(), tolerance_sq, max_beziers);
Geom::Path fit;
if (n_segs > 0) {
fit.start(b[0]);
for (int c = 0; c < n_segs; c++) {
fit.appendNew<Geom::CubicBezier>(b[4 * c + 1], b[4 * c + 2], b[4 * c + 3]);
}
}
delete[] b;
delete[] points_array;
return fit;
};
Path interpolateToPath2(std::vector<Point> const &points, double tolerance_sq, unsigned max_beziers)
{
std::vector<Point> b(max_beziers * 4);
int const n_segs = Geom::bezier_fit_cubic_r(b.data(), points.data(), points.size(), tolerance_sq, max_beziers);
Geom::Path fit;
if (n_segs > 0) {
fit.start(b[0]);
for (int c = 0; c < n_segs; c++) {
fit.appendNew<Geom::CubicBezier>(b[4 * c + 1], b[4 * c + 2], b[4 * c + 3]);
}
}
return fit;
};
int main()
{
std::vector<Point> data_vector;
for (auto i : data) {
data_vector.push_back(i);
}
const int num_repeats = 2000;
unsigned max_beziers = data_len*2;
double tolerance_sq = 0.01;
for (int rep = 0; rep < 3; rep++) {
std::clock_t start = std::clock();
for (int i = 0; i < num_repeats; i++) {
Point *bezier = new Point[max_beziers*4]; // large array on stack = not good, so allocate on heap
int n_segs = bezier_fit_cubic_r(bezier, data, data_len, tolerance_sq, max_beziers);
(void) n_segs;
delete[] bezier;
}
std::clock_t stop = std::clock();
std::cout << "bezier_fit_cubic_r C-array (" << num_repeats << "x): " << (stop - start) * (1000. / CLOCKS_PER_SEC) << " ms "
<< std::endl;
}
for (int rep = 0; rep < 3; rep++) {
std::clock_t start = std::clock();
for (int i = 0; i < num_repeats; i++) {
Path path = interpolateToPath(data_vector, tolerance_sq, max_beziers);
int n_segs = path.size();
(void) n_segs;
}
std::clock_t stop = std::clock();
std::cout << "bezier_fit_cubic_r 2Geom interoperability (" << num_repeats << "x): " << (stop - start) * (1000. / CLOCKS_PER_SEC) << " ms "
<< std::endl;
}
for (int rep = 0; rep < 3; rep++) {
std::clock_t start = std::clock();
for (int i = 0; i < num_repeats; i++) {
Path path = interpolateToPath2(data_vector, tolerance_sq, max_beziers);
int n_segs = path.size();
(void) n_segs;
}
std::clock_t stop = std::clock();
std::cout << "bezier_fit_cubic_r 2Geom interoperability 2nd version (" << num_repeats
<< "x): " << (stop - start) * (1000. / CLOCKS_PER_SEC) << " ms " << std::endl;
}
}
//
|