author | Claus Gittinger <cg@exept.de> |
Wed, 05 Jun 1996 13:54:34 +0200 | |
changeset 388 | 9f1c439ad66b |
parent 374 | a77f804c605e |
child 490 | ef43c7a69346 |
permissions | -rw-r--r-- |
278 | 1 |
" |
2 |
This class is based on a file from the Manchester Goodie library. |
|
3 |
It is not covered by the ST/X copyright and may be copied and used |
|
4 |
according the rules as stated by the athor and the manchester archive. |
|
5 |
||
6 |
The original readme was: |
|
7 |
||
8 |
||
9 |
The above file is a Manchester Goodie. It is distributed freely on condition |
|
10 |
that you observe these conditions in respect of the whole Goodie, and on |
|
11 |
any significant part of it which is separately transmitted or stored: |
|
12 |
* You must ensure that every copy includes this notice, and that |
|
13 |
source and author(s) of the material are acknowledged. |
|
14 |
* These conditions must be imposed on anyone who receives a copy. |
|
15 |
* The material shall not be used for commercial gain without the prior |
|
16 |
written consent of the author(s). |
|
17 |
||
18 |
For more information about the Manchester Goodies Library (from which |
|
19 |
this file was distributed) send e-mail: |
|
20 |
To: goodies-lib@cs.man.ac.uk |
|
21 |
Subject: help |
|
22 |
" |
|
23 |
||
24 |
||
25 |
||
26 |
Geometric subclass:#Spline |
|
27 |
instanceVariableNames:'controlPoints lines function firstDerivative secondDerivative |
|
28 |
thirdDerivative' |
|
29 |
classVariableNames:'' |
|
30 |
poolDictionaries:'' |
|
31 |
category:'Graphics-Geometry' |
|
32 |
! |
|
33 |
||
34 |
!Spline class methodsFor:'documentation'! |
|
35 |
||
36 |
copyright |
|
37 |
" |
|
38 |
This class is based on a file from the Manchester Goodie library. |
|
39 |
It is not covered by the ST/X copyright and may be copied and used |
|
40 |
according the rules as stated by the athor and the manchester archive. |
|
41 |
||
42 |
The original readme was: |
|
43 |
||
44 |
||
45 |
The above file is a Manchester Goodie. It is distributed freely on condition |
|
46 |
that you observe these conditions in respect of the whole Goodie, and on |
|
47 |
any significant part of it which is separately transmitted or stored: |
|
48 |
* You must ensure that every copy includes this notice, and that |
|
49 |
source and author(s) of the material are acknowledged. |
|
50 |
* These conditions must be imposed on anyone who receives a copy. |
|
51 |
* The material shall not be used for commercial gain without the prior |
|
52 |
written consent of the author(s). |
|
53 |
||
54 |
For more information about the Manchester Goodies Library (from which |
|
55 |
this file was distributed) send e-mail: |
|
56 |
To: goodies-lib@cs.man.ac.uk |
|
57 |
Subject: help |
|
58 |
" |
|
59 |
||
60 |
||
61 |
! |
|
62 |
||
63 |
documentation |
|
64 |
" |
|
65 |
Spline defines a path that includes an arbitrary collection of points |
|
280 | 66 |
connected by a third order curve. The curve passes through all controlPoints. |
67 |
Both open and closed curves are possible. |
|
278 | 68 |
|
279 | 69 |
[see also:] |
289 | 70 |
Polygon LineSegment Circle EllipticalArc |
331 | 71 |
Rectangle Curve Arrow ArrowedSpline |
72 |
GraphicsContext StrokingWrapper FillingWrapper |
|
279 | 73 |
|
278 | 74 |
[author:] |
75 |
scaletti@uxc.cso.uiuc.edu (Kurt J. Hebel) |
|
279 | 76 |
adapted to ST/X & minor fixes by Claus Gittinger |
278 | 77 |
" |
78 |
! |
|
79 |
||
80 |
examples |
|
81 |
" |
|
280 | 82 |
open spline; filled & unfilled: |
83 |
[exBegin] |
|
84 |
|v s| |
|
85 |
||
86 |
v := (View extent:100@100) openAndWait. |
|
87 |
||
88 |
s := Spline controlPoints: |
|
89 |
(Array with:(20@20) |
|
90 |
with:(80@80) |
|
91 |
with:(20@80)). |
|
92 |
||
93 |
v paint:Color blue. |
|
94 |
s displayFilledOn:v. |
|
95 |
||
96 |
v paint:Color red. |
|
97 |
s displayStrokedOn:v. |
|
98 |
[exEnd] |
|
99 |
||
100 |
closed spline; filled & unfilled: |
|
101 |
[exBegin] |
|
102 |
|v s| |
|
103 |
||
104 |
v := (View extent:100@100) openAndWait. |
|
105 |
||
106 |
s := Spline controlPoints: |
|
107 |
(Array with:(20@20) |
|
108 |
with:(80@80) |
|
109 |
with:(20@80) |
|
110 |
with:(20@20)). |
|
111 |
||
112 |
v paint:Color blue. |
|
113 |
s displayFilledOn:v. |
|
114 |
||
115 |
v paint:Color red. |
|
116 |
s displayStrokedOn:v. |
|
117 |
[exEnd] |
|
118 |
||
119 |
spiral: |
|
120 |
[exBegin] |
|
121 |
|v points s| |
|
122 |
||
123 |
v := View extent:(200 @ 200). |
|
124 |
||
125 |
v openAndWait. |
|
126 |
||
127 |
points := OrderedCollection new. |
|
128 |
90 to:10 by:-10 do:[:r | |
|
129 |
0 to:330 by:30 do:[:angle | |
|
130 |
|d| |
|
131 |
||
132 |
d := (angle / 360) * 10. |
|
133 |
points add:(Point r:r-d angle:angle) + (100@100) |
|
134 |
]. |
|
135 |
]. |
|
136 |
s := Spline controlPoints:points. |
|
137 |
||
138 |
v paint:Color red. |
|
139 |
s displayStrokedOn:v. |
|
140 |
[exEnd] |
|
141 |
interactive example: |
|
278 | 142 |
[exBegin] |
143 |
|v points eventCatcher| |
|
144 |
||
145 |
v := StandardSystemView extent:(450 @ 450). |
|
146 |
v label:'Spline Example - (click left/middle)'. |
|
147 |
||
148 |
points := OrderedCollection new. |
|
149 |
v openAndWait. |
|
150 |
||
151 |
eventCatcher := Plug new. |
|
152 |
eventCatcher respondTo:#handlesButtonPress:inView: |
|
153 |
with:[:butt :view | true]. |
|
154 |
eventCatcher respondTo:#buttonPress:x:y:view: |
|
155 |
with:[:butt :x :y :view | |
|
156 |
v paint:(Color white). |
|
157 |
v fillCircle:(x @ y) radius:3. |
|
158 |
points add:(x @ y). |
|
159 |
||
160 |
(butt == 1 or:[butt == #select]) ifFalse:[ |
|
161 |
v paint:(Color white). |
|
162 |
v fillCircle:(x @ y) radius:3. |
|
163 |
||
164 |
(Spline controlPoints:points) displayStrokedOn:v. |
|
165 |
||
166 |
points := OrderedCollection new. |
|
167 |
] |
|
168 |
]. |
|
169 |
||
170 |
v delegate:(eventCatcher) |
|
171 |
[exEnd] |
|
172 |
" |
|
173 |
! ! |
|
174 |
||
175 |
!Spline class methodsFor:'instance creation'! |
|
176 |
||
177 |
controlPoints:aSequentialCollectionOfPoints |
|
178 |
"return a new spline, which passes through aSequentialCollectionOfPoints" |
|
179 |
||
180 |
^ self new controlPoints:aSequentialCollectionOfPoints |
|
181 |
! ! |
|
182 |
||
183 |
!Spline methodsFor:'accessing'! |
|
184 |
||
185 |
controlPoints |
|
186 |
"return the collection of points through which the spline is |
|
187 |
to pass" |
|
188 |
||
189 |
^ controlPoints |
|
190 |
||
191 |
"Created: 8.5.1996 / 18:46:35 / cg" |
|
192 |
! |
|
193 |
||
194 |
controlPoints:aCollectionOfPoints |
|
195 |
"set the collection of points through which the spline is |
|
196 |
to pass" |
|
197 |
||
198 |
controlPoints := aCollectionOfPoints. |
|
199 |
lines := nil |
|
200 |
||
201 |
"Created: 8.5.1996 / 18:50:24 / cg" |
|
202 |
"Modified: 8.5.1996 / 19:32:57 / cg" |
|
203 |
! ! |
|
204 |
||
205 |
!Spline methodsFor:'converting'! |
|
206 |
||
283 | 207 |
asPointArray |
208 |
"return an array containing my approximated vertex points." |
|
209 |
||
210 |
^ self computeLineSegments |
|
211 |
||
212 |
"Created: 8.5.1996 / 20:44:09 / cg" |
|
213 |
! |
|
214 |
||
280 | 215 |
asPolygon |
278 | 216 |
"return a polygon, approximating the spline" |
217 |
||
218 |
^ Polygon vertices:(self computeLineSegments) |
|
219 |
||
280 | 220 |
"Created: 8.5.1996 / 20:15:37 / cg" |
221 |
! |
|
222 |
||
223 |
asPolyline |
|
224 |
"same as #asPolygon - for ST-80 compatibility" |
|
225 |
||
226 |
^ self asPolygon |
|
227 |
||
278 | 228 |
"Created: 8.5.1996 / 18:49:42 / cg" |
280 | 229 |
"Modified: 8.5.1996 / 20:15:59 / cg" |
278 | 230 |
! ! |
231 |
||
232 |
!Spline methodsFor:'displaying'! |
|
233 |
||
234 |
displayFilledOn:aGC |
|
235 |
"Display this Spline as a filled polygon from approximated lines." |
|
236 |
||
237 |
lines isNil ifTrue:[ |
|
238 |
lines := self computeLineSegments. |
|
239 |
]. |
|
240 |
||
241 |
aGC fillPolygon:lines |
|
242 |
||
243 |
"Modified: 8.5.1996 / 18:45:49 / cg" |
|
244 |
"Created: 8.5.1996 / 18:54:12 / cg" |
|
245 |
! |
|
246 |
||
247 |
displayStrokedOn:aGC |
|
248 |
"Display this Spline as a series of approximating lines." |
|
249 |
||
250 |
lines isNil ifTrue:[ |
|
251 |
lines := self computeLineSegments. |
|
252 |
]. |
|
253 |
||
254 |
"/ Plot the lines |
|
255 |
aGC displayPolygon:lines |
|
256 |
||
257 |
"Created: 8.5.1996 / 18:44:17 / cg" |
|
332
bb2dd1a968c2
bounds may be larger than controlPoint-bounds
Claus Gittinger <cg@exept.de>
parents:
331
diff
changeset
|
258 |
"Modified: 13.5.1996 / 11:19:14 / cg" |
278 | 259 |
! ! |
260 |
||
261 |
!Spline methodsFor:'private'! |
|
262 |
||
263 |
computeCurve |
|
264 |
"Compute an array for the derivatives at each knot." |
|
265 |
||
266 |
|size values cyclic second third secondFromLast thirdFromLast |
|
267 |
addedExtra| |
|
268 |
||
269 |
"/ Get the number of points, |
|
270 |
"/ and make an OrderedColleciton of all of the points." |
|
271 |
||
272 |
size := controlPoints size. |
|
273 |
function := OrderedCollection new:size. |
|
274 |
controlPoints do:[:point | function addLast:point]. |
|
275 |
||
276 |
"/ stop if the spline has not enough points for the derivation(s). |
|
277 |
size < 3 ifTrue: [^ self]. |
|
278 |
||
279 |
"/ Flag whether curve is cyclic or not. |
|
280 |
cyclic := size > 3 and: [function first = function last]. |
|
281 |
||
282 |
"/ Set up the values collection. The derivatives are computed from this. |
|
283 |
values := function copy. |
|
284 |
||
285 |
"/ Process cyclic curves differently. |
|
286 |
"/ Add the last two points to the beginning, |
|
287 |
"/ and the first two points to the end, so that the derivative calculation |
|
288 |
"/ can look at a cycle." |
|
289 |
cyclic ifTrue: [ |
|
290 |
second := values at: 2. |
|
291 |
third := values at: 3. |
|
292 |
thirdFromLast := values at: size - 2. |
|
293 |
secondFromLast := values at: size - 1. |
|
294 |
||
295 |
values addFirst: secondFromLast. |
|
296 |
values addFirst: thirdFromLast. |
|
297 |
values addLast: second. |
|
298 |
values addLast: third |
|
299 |
] ifFalse:[ |
|
300 |
size == 3 ifTrue:[ |
|
301 |
addedExtra := true. |
|
302 |
values addLast:(values last). |
|
303 |
] ifFalse:[ |
|
304 |
addedExtra := false |
|
305 |
] |
|
306 |
]. |
|
307 |
||
308 |
"/ Compute the derivatives of the values collection. |
|
309 |
self computeDerivatives:values. |
|
310 |
||
311 |
"/ Remove any extra points which were added if the Spline is cyclic. |
|
312 |
cyclic ifTrue: [ |
|
313 |
firstDerivative removeFirst. |
|
314 |
firstDerivative removeFirst. |
|
315 |
firstDerivative removeLast. |
|
316 |
firstDerivative removeLast. |
|
317 |
secondDerivative removeFirst. |
|
318 |
secondDerivative removeFirst. |
|
319 |
secondDerivative removeLast. |
|
320 |
secondDerivative removeLast. |
|
321 |
thirdDerivative removeFirst. |
|
322 |
thirdDerivative removeFirst. |
|
323 |
thirdDerivative removeLast. |
|
324 |
thirdDerivative removeLast |
|
325 |
] ifFalse:[ |
|
326 |
addedExtra ifTrue:[ |
|
327 |
firstDerivative removeLast. |
|
328 |
secondDerivative removeLast. |
|
329 |
thirdDerivative removeLast. |
|
330 |
] |
|
331 |
] |
|
332 |
||
333 |
"Created: 8.5.1996 / 18:34:43 / cg" |
|
334 |
"Modified: 8.5.1996 / 19:43:51 / cg" |
|
335 |
! |
|
336 |
||
337 |
computeDerivatives: values |
|
338 |
"Computes the first, second and third derivatives at each point |
|
339 |
in the collection values." |
|
340 |
||
341 |
|size "{Class: SmallInteger }" |
|
342 |
v b |
|
343 |
lastV lastB nextV nextB |
|
344 |
valuesI valuesI1 valuesI2 |
|
345 |
twoDerivI twoDerivI1| |
|
346 |
||
347 |
"/ Set up the derivative arrays. |
|
348 |
size := values size. |
|
349 |
size < 3 ifTrue: [ |
|
350 |
'SPLINE: not enough controlPoints' errorPrintNL. |
|
351 |
^ self |
|
352 |
]. |
|
353 |
||
354 |
firstDerivative := Array new:size. |
|
355 |
secondDerivative := Array new:size. |
|
356 |
thirdDerivative := Array new:size. |
|
357 |
||
358 |
"/ Compute the second derivative of the values. |
|
359 |
size > 3 ifTrue: [ |
|
360 |
lastV := 4.0. |
|
361 |
lastB := 6.0 * (values first - ((values at:2) * 2.0) + (values at:3)). |
|
362 |
v := Array new:size. |
|
363 |
b := Array new:size. |
|
364 |
v at: 1 put:lastV. |
|
365 |
b at: 1 put:lastB. |
|
366 |
valuesI := values at:2. |
|
367 |
valuesI1 := values at:3. |
|
368 |
size > 3 ifTrue: [valuesI2 := values at:4]. |
|
369 |
||
370 |
2 to:size-2 do: [:i | |
|
371 |
nextV := 4.0 - (1.0 / lastV). |
|
372 |
nextB := 6.0 * (valuesI - (valuesI1 * 2.0) + valuesI2) - (lastB / lastV). |
|
373 |
v at:i put:nextV. |
|
374 |
b at:i put:nextB. |
|
375 |
||
376 |
size-2 == i ifFalse: [ |
|
377 |
lastV := nextV. |
|
378 |
lastB := nextB. |
|
379 |
valuesI := valuesI1. |
|
380 |
valuesI1 := valuesI2. |
|
381 |
valuesI2 := values at:i+3 |
|
382 |
] |
|
383 |
]. |
|
384 |
||
385 |
secondDerivative at:size-1 put:nextB/nextV. |
|
386 |
||
387 |
size-2 to:2 by:-1 do: [:i | |
|
388 |
secondDerivative at:i |
|
389 |
put:(b at:i-1) |
|
390 |
- (secondDerivative at:i+1) / (v at:i-1) |
|
391 |
] |
|
392 |
]. |
|
393 |
||
394 |
secondDerivative at:1 put:0.0 asPoint. |
|
395 |
secondDerivative at:size put:0.0 asPoint. |
|
396 |
||
397 |
"/ Compute the values of the first and third derivative |
|
398 |
"/ from the second derivative and the values. |
|
399 |
||
400 |
valuesI := values at:1. |
|
401 |
valuesI1 := values at:2. |
|
402 |
twoDerivI := secondDerivative at:1. |
|
403 |
twoDerivI1 := secondDerivative at:2. |
|
404 |
1 to:size-1 do:[:i | |
|
405 |
firstDerivative at:i put:valuesI1 - valuesI - (twoDerivI * 2.0 + twoDerivI1 / 6.0). |
|
406 |
thirdDerivative at:i put:twoDerivI1 - twoDerivI. |
|
407 |
||
408 |
size-1 == i ifFalse:[ |
|
409 |
twoDerivI := twoDerivI1. |
|
410 |
twoDerivI1 := secondDerivative at:i+2. |
|
411 |
valuesI := valuesI1. |
|
412 |
valuesI1 := values at:i+2 |
|
413 |
] |
|
414 |
]. |
|
415 |
||
416 |
"/ The derivative collections should be OrderedCollections. |
|
417 |
||
418 |
firstDerivative := firstDerivative asOrderedCollection. |
|
419 |
secondDerivative := secondDerivative asOrderedCollection. |
|
420 |
thirdDerivative := thirdDerivative asOrderedCollection. |
|
421 |
||
422 |
"Created: 8.5.1996 / 18:39:31 / cg" |
|
423 |
"Modified: 8.5.1996 / 19:44:36 / cg" |
|
424 |
! |
|
425 |
||
426 |
computeLineSegments |
|
427 |
"compute a series of approximating lines." |
|
428 |
||
429 |
|lines |
|
430 |
n " {Class: SmallInteger }" |
|
431 |
nSteps " {Class: SmallInteger }" |
|
432 |
steps |
|
433 |
a b c d t| |
|
434 |
||
283 | 435 |
lines notNil ifTrue:[ ^ lines]. |
278 | 436 |
controlPoints size < 3 ifTrue:[^ controlPoints]. |
437 |
||
438 |
"/ Make sure that the function and its derivatives are up to date. |
|
439 |
self validateDerivatives. |
|
440 |
||
441 |
"/ Create a polygon for plotting. |
|
442 |
lines := OrderedCollection new. |
|
443 |
lines add:function first. |
|
444 |
||
445 |
"/ Approximate each spline knot. |
|
446 |
||
447 |
n := function size - 1. |
|
448 |
||
449 |
1 to:n do: [:k | |
|
450 |
"/ Compute the Taylor series coefficients. |
|
451 |
d := function at:k. |
|
452 |
c := firstDerivative at:k. |
|
453 |
b := (secondDerivative at:k) / 2.0. |
|
454 |
a := (thirdDerivative at:k) / 6.0. |
|
455 |
||
456 |
"/ Compute the number of approximating segments. |
|
457 |
steps := (secondDerivative at:k) abs + (secondDerivative at:k + 1) abs. |
|
458 |
steps := 5 max:(steps x + steps y) // 100. |
|
459 |
||
460 |
"/ Add each of the approximating line segments. |
|
461 |
nSteps := steps. |
|
462 |
1 to:nSteps do:[:j | |
|
463 |
t := j asFloat / steps. |
|
464 |
lines add: a * t + b * t + c * t + d |
|
465 |
]. |
|
466 |
||
467 |
"/ Add the last line to the real spline endpoint. |
|
468 |
lines add: (function at: k + 1) |
|
469 |
]. |
|
470 |
||
471 |
^ lines |
|
472 |
||
473 |
"Created: 8.5.1996 / 18:44:54 / cg" |
|
283 | 474 |
"Modified: 8.5.1996 / 20:45:10 / cg" |
278 | 475 |
! |
476 |
||
477 |
validateDerivatives |
|
478 |
"Make sure that the function and derivative arrays are still valid. |
|
479 |
If they are not, recompute them." |
|
480 |
||
481 |
|index "{ Class: SmallInteger }"| |
|
482 |
||
483 |
"/ |
|
484 |
"/ Compute the derivatives if the cached function has not been computed. |
|
485 |
"/ |
|
486 |
function isNil ifTrue:[ |
|
487 |
^ self computeCurve |
|
488 |
]. |
|
489 |
||
490 |
"/ Compute the derivatives if the cached function |
|
491 |
"/ and the collection of points do not agree." |
|
492 |
||
493 |
index := 1. |
|
494 |
controlPoints do:[:point | |
|
495 |
point ~~ (function at:index) ifTrue:[ |
|
496 |
^ self computeCurve |
|
497 |
]. |
|
498 |
index := index + 1 |
|
499 |
] |
|
500 |
||
501 |
"Created: 8.5.1996 / 18:31:46 / cg" |
|
502 |
"Modified: 8.5.1996 / 18:32:39 / cg" |
|
503 |
! ! |
|
504 |
||
505 |
!Spline methodsFor:'queries'! |
|
506 |
||
327 | 507 |
bounds |
508 |
"return the smallest enclosing rectangle" |
|
509 |
||
332
bb2dd1a968c2
bounds may be larger than controlPoint-bounds
Claus Gittinger <cg@exept.de>
parents:
331
diff
changeset
|
510 |
|l minX maxX minY maxY| |
327 | 511 |
|
332
bb2dd1a968c2
bounds may be larger than controlPoint-bounds
Claus Gittinger <cg@exept.de>
parents:
331
diff
changeset
|
512 |
lines isNil ifTrue:[ |
bb2dd1a968c2
bounds may be larger than controlPoint-bounds
Claus Gittinger <cg@exept.de>
parents:
331
diff
changeset
|
513 |
lines := self computeLineSegments. |
bb2dd1a968c2
bounds may be larger than controlPoint-bounds
Claus Gittinger <cg@exept.de>
parents:
331
diff
changeset
|
514 |
]. |
bb2dd1a968c2
bounds may be larger than controlPoint-bounds
Claus Gittinger <cg@exept.de>
parents:
331
diff
changeset
|
515 |
l := lines. |
bb2dd1a968c2
bounds may be larger than controlPoint-bounds
Claus Gittinger <cg@exept.de>
parents:
331
diff
changeset
|
516 |
|
bb2dd1a968c2
bounds may be larger than controlPoint-bounds
Claus Gittinger <cg@exept.de>
parents:
331
diff
changeset
|
517 |
minX := maxX := l first x rounded. |
bb2dd1a968c2
bounds may be larger than controlPoint-bounds
Claus Gittinger <cg@exept.de>
parents:
331
diff
changeset
|
518 |
minY := maxY := l first y rounded. |
bb2dd1a968c2
bounds may be larger than controlPoint-bounds
Claus Gittinger <cg@exept.de>
parents:
331
diff
changeset
|
519 |
l do:[:p | |
327 | 520 |
|x y| |
521 |
||
332
bb2dd1a968c2
bounds may be larger than controlPoint-bounds
Claus Gittinger <cg@exept.de>
parents:
331
diff
changeset
|
522 |
(x := p x rounded) < minX ifTrue:[ |
327 | 523 |
minX := x |
524 |
] ifFalse:[ |
|
525 |
x > maxX ifTrue:[ |
|
526 |
maxX := x |
|
527 |
] |
|
528 |
]. |
|
388 | 529 |
(y := p y rounded) < minY ifTrue:[ |
327 | 530 |
minY := y |
531 |
] ifFalse:[ |
|
532 |
y > maxY ifTrue:[ |
|
533 |
maxY := y |
|
534 |
] |
|
535 |
]. |
|
536 |
]. |
|
537 |
||
538 |
^ Rectangle left:minX right:maxX top:minY bottom:maxY |
|
539 |
||
540 |
"Created: 13.5.1996 / 00:27:29 / cg" |
|
332
bb2dd1a968c2
bounds may be larger than controlPoint-bounds
Claus Gittinger <cg@exept.de>
parents:
331
diff
changeset
|
541 |
"Modified: 13.5.1996 / 11:02:29 / cg" |
327 | 542 |
! |
543 |
||
374
a77f804c605e
added #canBeFilled for protocol completeness
Claus Gittinger <cg@exept.de>
parents:
332
diff
changeset
|
544 |
canBeFilled |
a77f804c605e
added #canBeFilled for protocol completeness
Claus Gittinger <cg@exept.de>
parents:
332
diff
changeset
|
545 |
"return true, if the receiver can be drawn as a filled geometric. |
a77f804c605e
added #canBeFilled for protocol completeness
Claus Gittinger <cg@exept.de>
parents:
332
diff
changeset
|
546 |
Always true here." |
a77f804c605e
added #canBeFilled for protocol completeness
Claus Gittinger <cg@exept.de>
parents:
332
diff
changeset
|
547 |
|
a77f804c605e
added #canBeFilled for protocol completeness
Claus Gittinger <cg@exept.de>
parents:
332
diff
changeset
|
548 |
^ true |
a77f804c605e
added #canBeFilled for protocol completeness
Claus Gittinger <cg@exept.de>
parents:
332
diff
changeset
|
549 |
|
a77f804c605e
added #canBeFilled for protocol completeness
Claus Gittinger <cg@exept.de>
parents:
332
diff
changeset
|
550 |
! |
a77f804c605e
added #canBeFilled for protocol completeness
Claus Gittinger <cg@exept.de>
parents:
332
diff
changeset
|
551 |
|
278 | 552 |
isCyclic |
553 |
"return true, if this spline represents a closed curve" |
|
554 |
||
555 |
^ controlPoints size > 3 and: [controlPoints first = controlPoints last]. |
|
556 |
||
557 |
"Created: 8.5.1996 / 18:47:50 / cg" |
|
558 |
! ! |
|
559 |
||
560 |
!Spline class methodsFor:'documentation'! |
|
561 |
||
562 |
version |
|
388 | 563 |
^ '$Header: /cvs/stx/stx/libbasic2/Spline.st,v 1.12 1996-06-05 11:54:34 cg Exp $' |
278 | 564 |
! ! |