author | Claus Gittinger <cg@exept.de> |
Thu, 06 Sep 2007 17:31:09 +0200 | |
changeset 1894 | 8bf137acc445 |
parent 1303 | 6ca5f36cdc63 |
permissions | -rw-r--r-- |
1303 | 1 |
"{ Package: 'stx:libbasic2' }" |
2 |
||
491 | 3 |
Geometric subclass:#Bezier |
4 |
instanceVariableNames:'start end controlPoint1 controlPoint2' |
|
5 |
classVariableNames:'ScaledFlatness' |
|
6 |
poolDictionaries:'' |
|
1303 | 7 |
category:'Graphics-Geometry-Objects' |
491 | 8 |
! |
9 |
||
10 |
!Bezier class methodsFor:'documentation'! |
|
11 |
||
12 |
documentation |
|
13 |
" |
|
14 |
Beziers represent parametric cubic curvea. |
|
15 |
||
16 |
[instance variables:] |
|
17 |
start <Point> startPoint of the curve. |
|
18 |
end <Point> endPoint of the curve. |
|
19 |
controlPoint1 <Point> control point. |
|
20 |
controlPoint2 <Point> control point. |
|
21 |
||
22 |
[class variables:] |
|
23 |
ScaledFlatness <Integer> curves flatness parameter |
|
24 |
||
25 |
[author:] |
|
26 |
unknown (based upon the PD path package) |
|
27 |
" |
|
28 |
! |
|
29 |
||
30 |
examples |
|
31 |
" |
|
32 |
bezier: |
|
33 |
[exBegin] |
|
34 |
|v s| |
|
35 |
||
36 |
v := (View extent:110@110) openAndWait. |
|
37 |
||
38 |
s := Bezier |
|
39 |
start:10@10 |
|
40 |
end:100@100 |
|
41 |
controlPoint1:50@50 |
|
42 |
controlPoint2:10@80. |
|
43 |
||
44 |
v paint:Color red. |
|
45 |
s displayStrokedOn:v. |
|
46 |
||
47 |
v paint:Color black. |
|
48 |
v displayPoint:10@10. |
|
49 |
v displayPoint:100@100. |
|
50 |
v displayPoint:50@50. |
|
51 |
v displayPoint:10@80. |
|
52 |
[exEnd] |
|
53 |
" |
|
54 |
! ! |
|
55 |
||
56 |
!Bezier class methodsFor:'instance creation'! |
|
57 |
||
58 |
start:startPoint end:endPoint controlPoint1:controlPoint1 controlPoint2:controlPoint2 |
|
59 |
"create & return a new bezier curve" |
|
60 |
||
61 |
^ self basicNew |
|
62 |
setStart:startPoint end:endPoint controlPoint1:controlPoint1 controlPoint2:controlPoint2 |
|
63 |
||
64 |
"Created: 12.2.1997 / 11:33:19 / cg" |
|
65 |
"Modified: 12.2.1997 / 14:25:59 / cg" |
|
66 |
! ! |
|
67 |
||
68 |
!Bezier class methodsFor:'class initialization'! |
|
69 |
||
70 |
initialize |
|
71 |
"initialize class constants" |
|
72 |
||
73 |
ScaledFlatness := (0.5 * Scale) rounded. |
|
74 |
||
75 |
" |
|
76 |
Bezier initialize |
|
77 |
" |
|
78 |
||
79 |
"Modified: 12.2.1997 / 14:26:26 / cg" |
|
80 |
! ! |
|
81 |
||
82 |
!Bezier methodsFor:'accessing'! |
|
83 |
||
84 |
controlPoint1 |
|
85 |
"return the first controlPoint" |
|
86 |
||
87 |
^ controlPoint1 |
|
88 |
||
89 |
"Modified: 12.2.1997 / 14:27:01 / cg" |
|
90 |
! |
|
91 |
||
92 |
controlPoint2 |
|
93 |
"return the second controlPoint" |
|
94 |
||
95 |
^ controlPoint2 |
|
96 |
||
97 |
"Created: 12.2.1997 / 11:33:18 / cg" |
|
98 |
"Modified: 12.2.1997 / 14:27:12 / cg" |
|
99 |
! |
|
100 |
||
101 |
end |
|
102 |
"return the endPoint" |
|
103 |
||
104 |
^ end |
|
105 |
||
106 |
"Created: 12.2.1997 / 11:33:18 / cg" |
|
107 |
"Modified: 12.2.1997 / 14:27:42 / cg" |
|
108 |
! |
|
109 |
||
110 |
start |
|
111 |
"return the startPoint" |
|
112 |
||
113 |
^ start |
|
114 |
||
115 |
"Modified: 12.2.1997 / 14:27:32 / cg" |
|
116 |
! ! |
|
117 |
||
118 |
!Bezier methodsFor:'comparing'! |
|
119 |
||
120 |
= anObject |
|
121 |
"return true, if the receiver and the arg represent the same bezier curve" |
|
122 |
||
123 |
self species == anObject species ifTrue:[ |
|
124 |
start = anObject start ifTrue:[ |
|
125 |
end = anObject end ifTrue:[ |
|
126 |
controlPoint1 = anObject controlPoint1 ifTrue:[ |
|
127 |
controlPoint2 = anObject controlPoint2 ifTrue:[ |
|
128 |
^ true |
|
129 |
] |
|
130 |
] |
|
131 |
] |
|
132 |
] |
|
133 |
]. |
|
134 |
^ false. |
|
135 |
||
136 |
"Modified: 12.2.1997 / 14:29:38 / cg" |
|
137 |
! |
|
138 |
||
139 |
hash |
|
140 |
"return an integer useful as hashKey; |
|
141 |
redefined, since = is redefined" |
|
142 |
||
143 |
^ start hash + end hash + controlPoint1 hash + controlPoint2 hash |
|
144 |
||
145 |
"Modified: 12.2.1997 / 14:30:11 / cg" |
|
146 |
! ! |
|
147 |
||
148 |
!Bezier methodsFor:'converting'! |
|
149 |
||
150 |
asLine |
|
151 |
"return a line from the startPoint to the endPoint" |
|
152 |
||
153 |
^ LineSegment from:start to:end |
|
154 |
||
155 |
"Created: 12.2.1997 / 11:33:19 / cg" |
|
156 |
"Modified: 12.2.1997 / 14:31:01 / cg" |
|
157 |
! |
|
158 |
||
159 |
asPolyline |
|
160 |
"return a polygon which approximates the curve" |
|
161 |
||
162 |
^ Polygon vertices:(self computePoints) |
|
163 |
||
164 |
"Modified: 12.2.1997 / 14:31:28 / cg" |
|
165 |
! ! |
|
166 |
||
167 |
!Bezier methodsFor:'displaying'! |
|
168 |
||
169 |
displayFilledOn: aGraphicsContext |
|
170 |
"report an error: cannot be filled." |
|
171 |
||
172 |
self shouldNotImplement |
|
173 |
||
174 |
"Modified: 12.2.1997 / 14:31:49 / cg" |
|
175 |
! |
|
176 |
||
177 |
displayStrokedOn: aGraphicsContext |
|
178 |
"display the curve as an outline" |
|
179 |
||
180 |
aGraphicsContext displayPolygon:(self computePoints) |
|
181 |
||
182 |
"Modified: 12.2.1997 / 14:33:09 / cg" |
|
183 |
! ! |
|
184 |
||
185 |
!Bezier methodsFor:'private'! |
|
186 |
||
187 |
addPointsFromStartX:p1X y:p1Y control1X:p2X y:p2Y control2X:p3X y:p3Y endX:p4X y:p4Y to:aCollection |
|
188 |
"actual workHorse for point computation" |
|
189 |
||
492
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
190 |
|x1 y1 x2 y2 x3 y3 t d dist dx3 dy3 |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
191 |
midX12 midY12 midX23 midY23 x1p y1p xm ym| |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
192 |
|
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
193 |
%{ /* OPTIONAL */ |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
194 |
|
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
195 |
/* |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
196 |
* easy inlining; all math is done in smallIntegers |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
197 |
*/ |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
198 |
if (__bothSmallInteger(p1X, p1Y) |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
199 |
&& __bothSmallInteger(p2X, p2Y) |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
200 |
&& __bothSmallInteger(p3X, p3Y) |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
201 |
&& __bothSmallInteger(p4X, p4Y) |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
202 |
&& __isSmallInteger(@global(ScaledFlatness)) |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
203 |
&& __isFloat(@global(InverseScale)) |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
204 |
) { |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
205 |
int _x1 = __intVal(p1X); |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
206 |
int _y1 = __intVal(p1Y); |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
207 |
int _x2 = __intVal(p2X); |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
208 |
int _y2 = __intVal(p2Y); |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
209 |
int _x3 = __intVal(p3X); |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
210 |
int _y3 = __intVal(p3Y); |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
211 |
int _p4X = __intVal(p4X); |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
212 |
int _p4Y = __intVal(p4Y); |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
213 |
int _flatness = __intVal(@global(ScaledFlatness)); |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
214 |
double _flatnessD = (double)_flatness; |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
215 |
double _invScaleD = __floatVal(@global(InverseScale)); |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
216 |
|
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
217 |
for (;;) { |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
218 |
int _midX12, _midY12, _midX23, _midY23; |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
219 |
int _x1p, _y1p, _xm, _ym; |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
220 |
extern double sqrt(), ceil(), floor(); |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
221 |
# define round(x) (((x) < 0) ? ceil((x) - 0.5) : floor((x) + 0.5)) |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
222 |
|
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
223 |
if (_p4X == _x1) { |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
224 |
int _dX1, _dX2; |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
225 |
|
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
226 |
_dX1 = _x2 - _x1; if (_dX1 < 0) _dX1 = -_dX1; |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
227 |
_dX2 = _x3 - _x1; if (_dX2 < 0) _dX2 = -_dX2; |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
228 |
if ((_dX1 <= _flatness) && (_dX2 <= _flatness)) break; |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
229 |
} else { |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
230 |
int _dX3, _dY3, _dX3Abs, _dY3Abs; |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
231 |
|
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
232 |
_dX3 = _dX3Abs = (_p4X - _x1); if (_dX3 < 0) _dX3Abs = -_dX3Abs; |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
233 |
_dY3 = _dY3Abs = (_p4Y - _y1); if (_dY3 < 0) _dY3Abs = -_dY3Abs; |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
234 |
|
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
235 |
if (_dX3Abs >= _dY3Abs) { |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
236 |
double _slope = (double)_dY3 / (double)_dX3; |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
237 |
double _t; |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
238 |
int _d, _dist; |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
239 |
|
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
240 |
_t = _slope*_slope + 1.0; |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
241 |
_t = sqrt(_t) * _flatnessD; |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
242 |
_t = round(_t); |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
243 |
_d = _t; |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
244 |
|
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
245 |
_t = _slope * (_x2-_x1); |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
246 |
_t = round(_t); |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
247 |
_dist = _t; |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
248 |
_dist -= (_y2-_y1); |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
249 |
if ((_dist >= 0) ? (_dist <= _d) : ((_dist + _d) >= 0)) { |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
250 |
_t = _slope * (_x3-_x1); |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
251 |
_t = round(_t); |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
252 |
_dist = _t; |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
253 |
_dist -= (_y3-_y1); |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
254 |
if ((_dist >= 0) ? (_dist <= _d) : ((_dist + _d) >= 0)) break; |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
255 |
} |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
256 |
} else { |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
257 |
double _slope = (double)_dX3 / (double)_dY3; |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
258 |
double _t; |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
259 |
int _d, _dist; |
491 | 260 |
|
492
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
261 |
_t = _slope*_slope + 1.0; |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
262 |
_t = sqrt(_t) * _flatnessD; |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
263 |
_t = round(_t); |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
264 |
_d = _t; |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
265 |
|
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
266 |
_t = _slope * (_y2-_y1); |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
267 |
_t = round(_t); |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
268 |
_dist = _t; |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
269 |
_dist -= (_x2-_x1); |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
270 |
if ((_dist >= 0) ? (_dist <= _d) : ((_dist + _d) >= 0)) { |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
271 |
_t = _slope * (_y3-_y1); |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
272 |
_t = round(_t); |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
273 |
_dist = _t; |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
274 |
_dist -= (_x3-_x1); |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
275 |
if ((_dist >= 0) ? (_dist <= _d) : ((_dist + _d) >= 0)) break; |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
276 |
} |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
277 |
} |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
278 |
} |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
279 |
|
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
280 |
# undef round |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
281 |
|
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
282 |
_midX12 = (_x1 + _x2) / 2; |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
283 |
_midY12 = (_y1 + _y2) / 2; |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
284 |
_midX23 = (_x2 + _x3) / 2; |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
285 |
_midY23 = (_y2 + _y3) / 2; |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
286 |
|
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
287 |
_x3 = (_x3 + _p4X) / 2; |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
288 |
_y3 = (_y3 + _p4Y) / 2; |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
289 |
_x1p = (_midX12 + _midX23) / 2; |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
290 |
_y1p = (_midY12 + _midY23) / 2; |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
291 |
_x2 = (_midX23 + _x3) / 2; |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
292 |
_y2 = (_midY23 + _y3) / 2; |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
293 |
_xm = (_x1p + _x2) / 2; |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
294 |
_ym = (_y1p + _y2) / 2; |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
295 |
|
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
296 |
{ |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
297 |
static struct inlineCache addPoints = __ILC9(@line); |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
298 |
|
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
299 |
(*addPoints.ilc_func)(self, |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
300 |
@symbol(addPointsFromStartX:y:control1X:y:control2X:y:endX:y:to:), |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
301 |
nil, |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
302 |
&addPoints, |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
303 |
__MKSMALLINT(_x1), __MKSMALLINT(_y1), |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
304 |
__MKSMALLINT(_midX12), __MKSMALLINT(_midY12), |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
305 |
__MKSMALLINT(_x1p), __MKSMALLINT(_y1p), |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
306 |
__MKSMALLINT(_xm), __MKSMALLINT(_ym), |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
307 |
aCollection |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
308 |
); |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
309 |
} |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
310 |
|
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
311 |
_x1 = _xm; |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
312 |
_y1 = _ym; |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
313 |
} |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
314 |
{ |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
315 |
static struct inlineCache add = __ILC1(@line); |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
316 |
OBJ newPoint; |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
317 |
double d_x, d_y; |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
318 |
|
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
319 |
d_x = _p4X * _invScaleD; |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
320 |
d_y = _p4Y * _invScaleD; |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
321 |
newPoint = __MKPOINT_DOUBLE( d_x, d_y); |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
322 |
|
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
323 |
(*add.ilc_func)(aCollection, |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
324 |
@symbol(add:), |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
325 |
nil, |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
326 |
&add, |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
327 |
newPoint |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
328 |
); |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
329 |
} |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
330 |
RETURN (self); |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
331 |
} |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
332 |
%}. |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
333 |
|
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
334 |
x1 := p1X. y1 := p1Y. |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
335 |
x2 := p2X. y2 := p2Y. |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
336 |
x3 := p3X. y3 := p3Y. |
491 | 337 |
|
338 |
[ |
|
492
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
339 |
p4X = x1 ifTrue:[ |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
340 |
"p4X = x1, i.e. dx = 0" |
590 | 341 |
(x2 - x1) abs <= ScaledFlatness |
342 |
and: [(x3 - x1) abs <= ScaledFlatness] |
|
491 | 343 |
] ifFalse:[ |
492
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
344 |
dx3 := p4X - x1. |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
345 |
dy3 := p4Y - y1. |
491 | 346 |
|
590 | 347 |
(dx3 abs >= dy3 abs) ifTrue:[ |
491 | 348 |
t := dy3 asFloat / dx3. |
349 |
d := ((1.0 + (t * t)) sqrt * ScaledFlatness) rounded. |
|
492
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
350 |
dist := (t * (x2 - x1)) rounded - (y2 - y1). |
491 | 351 |
|
352 |
(dist >= 0 ifTrue: [dist <= d] ifFalse: [dist + d >= 0]) |
|
492
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
353 |
and:[dist := (t * (x3 - x1)) rounded - (y3 - y1). |
491 | 354 |
dist >= 0 ifTrue: [dist <= d] ifFalse: [dist + d >= 0]] |
355 |
] ifFalse:[ |
|
356 |
t := dx3 asFloat / dy3. |
|
357 |
d := ((1.0 + (t * t)) sqrt * ScaledFlatness) rounded. |
|
492
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
358 |
dist := (t * (y2 - y1)) rounded - (x2 - x1). |
491 | 359 |
(dist >= 0 ifTrue: [dist <= d] ifFalse: [dist + d >= 0]) |
492
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
360 |
and:[dist := (t * (y3 - y1)) rounded - (x3 - x1). |
491 | 361 |
dist >= 0 ifTrue: [dist <= d] ifFalse: [dist + d >= 0]] |
362 |
] |
|
363 |
] |
|
364 |
] whileFalse:[ |
|
365 |
midX12 := (x1 + x2) // 2. |
|
366 |
midY12 := (y1 + y2) // 2. |
|
492
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
367 |
midX23 := (x2 + x3) // 2. |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
368 |
midY23 := (y2 + y3) // 2. |
491 | 369 |
|
492
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
370 |
x3 := (x3 + p4X) // 2. |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
371 |
y3 := (y3 + p4Y) // 2. |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
372 |
x1p := (midX12 + midX23) // 2. |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
373 |
y1p := (midY12 + midY23) // 2. |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
374 |
x2 := (midX23 + x3) // 2. |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
375 |
y2 := (midY23 + y3) // 2. |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
376 |
xm := (x1p + x2) // 2. |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
377 |
ym := (y1p + y2) // 2. |
491 | 378 |
|
379 |
self |
|
492
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
380 |
addPointsFromStartX:x1 y:y1 |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
381 |
control1X:midX12 y:midY12 |
491 | 382 |
control2X:x1p y:y1p |
383 |
endX:xm y:ym |
|
384 |
to:aCollection. |
|
492
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
385 |
x1 := xm. |
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
386 |
y1 := ym. |
491 | 387 |
]. |
492
56d74636cb69
inline code for point-generation
Claus Gittinger <cg@exept.de>
parents:
491
diff
changeset
|
388 |
|
491 | 389 |
aCollection add: (p4X asFloat * InverseScale) @ (p4Y asFloat * InverseScale) |
390 |
||
391 |
"Created: 12.2.1997 / 15:05:52 / cg" |
|
392 |
"Modified: 12.2.1997 / 15:10:34 / cg" |
|
393 |
! |
|
394 |
||
395 |
computeBounds |
|
396 |
"return the reactngle which encloses the curve." |
|
397 |
||
398 |
^ self class boundingRectangleForPoints:(self computePoints). |
|
399 |
||
400 |
"Modified: 12.2.1997 / 14:33:45 / cg" |
|
401 |
! |
|
402 |
||
403 |
computePoints |
|
404 |
"compute the points along the bezier - return a collection of points" |
|
405 |
||
406 |
|pointCollection| |
|
407 |
||
408 |
pointCollection := OrderedCollection new. |
|
409 |
pointCollection add:start. |
|
410 |
||
411 |
self |
|
412 |
addPointsFromStartX: (start x * Scale) rounded |
|
413 |
y: (start y * Scale) rounded |
|
414 |
control1X: (controlPoint1 x * Scale) rounded |
|
415 |
y: (controlPoint1 y * Scale) rounded |
|
416 |
control2X: (controlPoint2 x * Scale) rounded |
|
417 |
y: (controlPoint2 y * Scale) rounded |
|
418 |
endX: (end x * Scale) rounded |
|
419 |
y: (end y * Scale) rounded |
|
420 |
to: pointCollection. |
|
421 |
^ pointCollection |
|
422 |
||
423 |
"Modified: 12.2.1997 / 15:04:07 / cg" |
|
424 |
! |
|
425 |
||
426 |
setStart:startPoint end:endPoint controlPoint1:cp1 controlPoint2:cp2 |
|
427 |
start := startPoint. |
|
428 |
end := endPoint. |
|
429 |
controlPoint1 := cp1. |
|
430 |
controlPoint2 := cp2 |
|
431 |
||
432 |
"Modified: 12.2.1997 / 14:48:19 / cg" |
|
433 |
! ! |
|
434 |
||
435 |
!Bezier methodsFor:'testing'! |
|
436 |
||
437 |
outlineIntersects:aRectangle |
|
438 |
"return true, if the curve intersects a rectangle" |
|
439 |
||
440 |
^ self class vertices:(self computePoints) intersectsRectangle:aRectangle |
|
441 |
||
442 |
"Created: 12.2.1997 / 11:33:18 / cg" |
|
443 |
"Modified: 12.2.1997 / 14:50:35 / cg" |
|
444 |
! ! |
|
445 |
||
446 |
!Bezier methodsFor:'transforming'! |
|
447 |
||
448 |
scaledBy:scaleFactor |
|
449 |
"return a copy of the receiver, which is scaled by some amount" |
|
450 |
||
451 |
^ self species |
|
452 |
start:(start * scaleFactor) |
|
453 |
end:(end * scaleFactor) |
|
454 |
controlPoint1:(controlPoint1 * scaleFactor) |
|
455 |
controlPoint2:(controlPoint2 * scaleFactor) |
|
456 |
||
457 |
"Created: 12.2.1997 / 11:33:18 / cg" |
|
458 |
"Modified: 12.2.1997 / 14:51:34 / cg" |
|
459 |
! |
|
460 |
||
461 |
translatedBy:translation |
|
462 |
"return a copy of the receiver, which is translated by some amount" |
|
463 |
||
464 |
^ self species |
|
465 |
start:(start + translation) |
|
466 |
end:(end + translation) |
|
467 |
controlPoint1:(controlPoint1 + translation) |
|
468 |
controlPoint2:(controlPoint2 + translation) |
|
469 |
||
470 |
"Modified: 12.2.1997 / 14:52:12 / cg" |
|
471 |
! ! |
|
472 |
||
473 |
!Bezier class methodsFor:'documentation'! |
|
474 |
||
475 |
version |
|
1303 | 476 |
^ '$Header: /cvs/stx/stx/libbasic2/Bezier.st,v 1.5 2003-08-29 17:31:58 cg Exp $' |
491 | 477 |
! ! |
1303 | 478 |
|
491 | 479 |
Bezier initialize! |