-
Notifications
You must be signed in to change notification settings - Fork 1
/
BezierSegment.pde
90 lines (76 loc) · 2.53 KB
/
BezierSegment.pde
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
class BezierSegment implements IVectorFunction {
PVector p0, p1;
PVector c0, c1;
BezierSegment(
float startX, float startY,
float startControlX, float startControlY,
float endControlX, float endControlY,
float endX, float endY) {
p0 = new PVector(startX, startY);
c0 = new PVector(startControlX, startControlY);
c1 = new PVector(endControlX, endControlY);
p1 = new PVector(endX, endY);
}
BezierSegment(PVector start, PVector startControl, PVector endControl, PVector end) {
p0 = start;
c0 = startControl;
c1 = endControl;
p1 = end;
}
BezierSegment(LineSegment start, LineSegment end) {
p0 = new PVector(start.p0.x, start.p0.y);
c0 = new PVector(start.p1.x, start.p1.y);
c1 = new PVector(end.p1.x, end.p1.y);
p1 = new PVector(end.p0.x, end.p0.y);
}
void draw(PGraphics g) {
g.bezier(p0.x, p0.y, c0.x, c0.y, c1.x, c1.y, p1.x, p1.y);
}
/**
* Simpler formulation of De Casteljau algorithm for cubic Béziers.
* @see http://stackoverflow.com/a/879213
* @author Naaff
*/
void draw(PGraphics g, float t0, float t1) {
float u0 = 1.0 - t0;
float u1 = 1.0 - t1;
float qxa = p0.x*u0*u0 + c0.x*2*t0*u0 + c1.x*t0*t0;
float qxb = p0.x*u1*u1 + c0.x*2*t1*u1 + c1.x*t1*t1;
float qxc = c0.x*u0*u0 + c1.x*2*t0*u0 + p1.x*t0*t0;
float qxd = c0.x*u1*u1 + c1.x*2*t1*u1 + p1.x*t1*t1;
float qya = p0.y*u0*u0 + c0.y*2*t0*u0 + c1.y*t0*t0;
float qyb = p0.y*u1*u1 + c0.y*2*t1*u1 + c1.y*t1*t1;
float qyc = c0.y*u0*u0 + c1.y*2*t0*u0 + p1.y*t0*t0;
float qyd = c0.y*u1*u1 + c1.y*2*t1*u1 + p1.y*t1*t1;
float xa = qxa*u0 + qxc*t0;
float xb = qxa*u1 + qxc*t1;
float xc = qxb*u0 + qxd*t0;
float xd = qxb*u1 + qxd*t1;
float ya = qya*u0 + qyc*t0;
float yb = qya*u1 + qyc*t1;
float yc = qyb*u0 + qyd*t0;
float yd = qyb*u1 + qyd*t1;
g.bezier(xa, ya, xb, yb, xc, yc, xd, yd);
}
void drawControls(PGraphics g) {
g.line(p0.x, p0.y, c0.x, c0.y);
g.line(p1.x, p1.y, c1.x, c1.y);
}
PVector getPoint(float t) {
return new PVector(
bezierInterpolation(p0.x, c0.x, c1.x, p1.x, t),
bezierInterpolation(p0.y, c0.y, c1.y, p1.y, t));
}
/**
* @see http://stackoverflow.com/a/4060392
* @author michal@michalbencur.com
*/
private float bezierInterpolation(float a, float b, float c, float d, float t) {
float t2 = t * t;
float t3 = t2 * t;
return a + (-a * 3 + t * (3 * a - a * t)) * t
+ (3 * b + t * (-6 * b + b * 3 * t)) * t
+ (c * 3 - c * 3 * t) * t2
+ d * t3;
}
}