-
Notifications
You must be signed in to change notification settings - Fork 0
/
stroke.pde
143 lines (110 loc) · 3.37 KB
/
stroke.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
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
134
135
136
137
138
139
140
141
142
143
/**
*
* @author Thomas Lindemeier
* @date 28.10.2012
*
*/
class Stroke implements Iterable<PVector>
{
public color brushColor = color(0, 0, 0);
public float brushRadius = 16;
// control points of the stroke
private Vector<PVector> points = new Vector<PVector>();
Stroke() {}
void add(int x, int y) { points.add(new PVector(x, y)); }
public int size() { return points.size(); }
void add(PVector vec) { points.add(vec); }
void clear() { points.clear(); }
Iterator<PVector> iterator() { return points.iterator(); }
void render(final PGraphics pg) {
pg.noFill();
pg.smooth();
pg.strokeCap(ROUND); // make round caps
pg.strokeJoin(ROUND); // let the strokes join round
color c = color(red(brushColor), green(brushColor), blue(brushColor), renderAlpha);
pg.stroke(c);
pg.strokeWeight(2*brushRadius);
pg.beginShape();
for (PVector p : this)
pg.vertex(p.x, p.y);
pg.endShape();
}
void renderTextured(final PGraphics pg)
{
color c = color(red(brushColor), green(brushColor), blue(brushColor), renderAlpha);
pg.stroke(c);
pg.fill(c);
pg.strokeWeight(1);
// short stroke
if (points.size() < 2)
{
if (points.isEmpty()) return;
PVector p = points.get(0);
pg.ellipse(p.x, p.y, 2*brushRadius, 2*brushRadius);
return;
}
pg.noStroke();
pg.noFill();
// draw start
PVector p0;
PVector p1;
PVector p2;
float mag, dx, dy, dist;
// compute total length of stroke
float strokeLength = 0;
for (int i=0; i < points.size() - 1; ++i)
{
p0 = points.get(i);
p1 = points.get(i+1);
strokeLength += sqrt((p1.x-p0.x)*(p1.x-p0.x)+(p1.y-p0.y)*(p1.y-p0.y));
}
p0 = points.get(0);
p1 = points.get(1);
dx = p1.y - p0.y;
dy = p0.x - p1.x;
mag = sqrt(dx*dx + dy*dy);
dx /= mag;
dy /= mag;
float textureU = 0;
float textureV = 0;
pg.textureMode(IMAGE);
final int tw = brushTexture.width;
final int th = brushTexture.height;
pg.beginShape(TRIANGLE_STRIP);
//brush texture
pg.texture(brushTexture);
pg.tint(brushColor);
pg.vertex(p0.x + brushRadius * dx, p0.y + brushRadius * dy, textureU*tw, 0);
pg.vertex(p0.x - brushRadius * dx, p0.y - brushRadius * dy, textureU*tw, th);
//draw middle stroke
for (int i=1; i < points.size() - 1; ++i)
{
p0 = points.get(i-1);
p1 = points.get(i);
p2 = points.get(i+1);
// (p1-p2) and rotate 90 degrees
dx = p2.y - p0.y;
dy = p0.x - p2.x;
mag = sqrt(dx*dx + dy*dy);
dx /= mag;
dy /= mag;
dist = sqrt((p1.x-p0.x)*(p1.x-p0.x)+(p1.y-p0.y)*(p1.y-p0.y));
textureU += dist / strokeLength;
pg.vertex(p1.x + brushRadius * dx, p1.y + brushRadius * dy, textureU*tw, 0);
pg.vertex(p1.x - brushRadius * dx, p1.y - brushRadius * dy, textureU*tw, th);
}
//draw end
p0 = points.get(points.size()-2);
p1 = points.get(points.size()-1);
dx = p1.y - p0.y;
dy = p0.x - p1.x;
mag = sqrt(dx*dx + dy*dy);
dx /= mag;
dy /= mag;
dist = sqrt((p1.x-p0.x)*(p1.x-p0.x)+(p1.y-p0.y)*(p1.y-p0.y));
textureU += dist / strokeLength;
pg.vertex(p1.x + brushRadius * dx, p1.y + brushRadius * dy, textureU*tw, 0);
pg.vertex(p1.x - brushRadius * dx, p1.y - brushRadius * dy, textureU*tw, th);
pg.endShape();
}
}