-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathspiro_wrapper.h
More file actions
101 lines (86 loc) · 2.48 KB
/
Copy pathspiro_wrapper.h
File metadata and controls
101 lines (86 loc) · 2.48 KB
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
#ifndef SPIRO_WRAPPER_H_
#define SPIRO_WRAPPER_H_
#include <iostream>
#include <memory>
#include <vector>
namespace spiro {
enum class SpiroCPType : char {
CORNER = 'v',
G4 = 'o',
G2 = 'c',
LEFT = '[',
RIGHT = ']',
END = 'z',
ANCHOR = 'a',
HANDLE = 'h'
};
struct SpiroCP {
double x;
double y;
SpiroCPType ty;
};
struct KnotResult {
enum Type { MOVE, LINE, CURVE };
Type type;
double fromX, fromY;
std::vector<std::pair<double, double>> points;
void Println() {
switch (type) {
case Type::MOVE:
std::cout << "Move: from (" << fromX << ", " << fromY << ") to ("
<< points[0].first << ", " << points[0].second << ")"
<< std::endl;
break;
case Type::LINE:
std::cout << "Line: from (" << fromX << ", " << fromY << ") to ("
<< points[0].first << ", " << points[0].second << ")"
<< std::endl;
break;
case Type::CURVE:
std::cout << "Curve: P0 (" << fromX << ", " << fromY << "), "
<< "P1 (" << points[0].first << ", " << points[0].second
<< "), "
<< "P2 (" << points[1].first << ", " << points[1].second
<< "), "
<< "P3 (" << points[2].first << ", " << points[2].second
<< "), " << std::endl;
break;
default:
break;
}
}
bool PointAtCubicBezier(double t, double *x, double *y) const {
if (t < 0 || t > 1 || type != Type::CURVE || points.size() != 4) {
return false;
}
const double co0 = (1 - t) * (1 - t) * (1 - t);
const double co1 = (1 - t) * (1 - t) * t * 3;
const double co2 = (1 - t) * t * t * 3;
const double co3 = t * t * t;
*x = fromX.first * co0 + points[0].first * co1 + points[1].first * co2 +
points[2].first * co3;
*y = fromY.second * co0 + points[0].second * co1 +
points[1].second * co2 + points[2].second * co3;
return true;
}
};
class SpiroWrapper {
public:
SpiroWrapper(const std::vector<SpiroCP> &src, bool is_closed = false);
~SpiroWrapper();
bool Compute();
bool Valid() const;
const std::vector<KnotResult> &Results() const;
private:
// Disable Implict Construct, Copy, Move
SpiroWrapper();
SpiroWrapper(const SpiroWrapper &);
SpiroWrapper &operator=(const SpiroWrapper &);
int n_;
bool is_closed_;
bool valid_, computed_;
std::vector<SpiroCP> src_;
std::vector<KnotResult> results_;
};
} // namespace spiro
#endif