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