author | Claus Gittinger <cg@exept.de> |
Thu, 09 Jun 2016 12:36:55 +0200 | |
changeset 3898 | c90424dba938 |
parent 2152 | ad1307561fe5 |
permissions | -rw-r--r-- |
282 | 1 |
" |
2 |
COPYRIGHT (c) 1996 by Claus Gittinger |
|
3 |
All Rights Reserved |
|
4 |
||
5 |
This software is furnished under a license and may be used |
|
6 |
only in accordance with the terms of that license and with the |
|
7 |
inclusion of the above copyright notice. This software may not |
|
8 |
be provided or otherwise made available to, or used by, any |
|
9 |
other person. No title to or ownership of the software is |
|
10 |
hereby transferred. |
|
11 |
" |
|
1302 | 12 |
"{ Package: 'stx:libbasic2' }" |
13 |
||
286 | 14 |
Geometric subclass:#LineSegment |
15 |
instanceVariableNames:'startPoint endPoint' |
|
282 | 16 |
classVariableNames:'' |
17 |
poolDictionaries:'' |
|
1303 | 18 |
category:'Graphics-Geometry-Objects' |
282 | 19 |
! |
20 |
||
286 | 21 |
!LineSegment class methodsFor:'documentation'! |
282 | 22 |
|
23 |
copyright |
|
24 |
" |
|
25 |
COPYRIGHT (c) 1996 by Claus Gittinger |
|
26 |
All Rights Reserved |
|
27 |
||
28 |
This software is furnished under a license and may be used |
|
29 |
only in accordance with the terms of that license and with the |
|
30 |
inclusion of the above copyright notice. This software may not |
|
31 |
be provided or otherwise made available to, or used by, any |
|
32 |
other person. No title to or ownership of the software is |
|
33 |
hereby transferred. |
|
34 |
" |
|
35 |
||
36 |
||
37 |
! |
|
38 |
||
39 |
documentation |
|
40 |
" |
|
286 | 41 |
LineSegments represent a line consisting of start and endPoint |
42 |
(actually, its a vector, since the direction makes a difference when |
|
43 |
instances are compared using #=). |
|
282 | 44 |
|
45 |
[author:] |
|
46 |
Claus Gittinger |
|
47 |
||
48 |
[see also:] |
|
320 | 49 |
Rectangle Polygon EllipticalArc Circle Spline Curve |
331 | 50 |
Point Arrow ArrowedSpline |
282 | 51 |
GraphicsContext |
317 | 52 |
StrokingWrapper |
282 | 53 |
" |
54 |
||
317 | 55 |
! |
56 |
||
57 |
examples |
|
58 |
" |
|
319 | 59 |
low leel use: |
317 | 60 |
[exBegin] |
61 |
|v l| |
|
62 |
||
63 |
v := (View extent:100@100) openAndWait. |
|
64 |
||
65 |
l := LineSegment from:10@10 to:90@90. |
|
66 |
||
67 |
v paint:Color red. |
|
68 |
l displayStrokedOn:v. |
|
69 |
||
1302 | 70 |
l setStart:90@10 end:10@90. |
317 | 71 |
v paint:Color blue. |
72 |
l displayStrokedOn:v. |
|
73 |
[exEnd] |
|
319 | 74 |
as component (automatic redraw): |
75 |
[exBegin] |
|
76 |
|v l| |
|
77 |
||
78 |
v := View extent:100@100. |
|
79 |
||
80 |
l := LineSegment from:10@10 to:90@90. |
|
81 |
v addComponent:(StrokingWrapper on:l). |
|
82 |
||
83 |
l := LineSegment from:90@10 to:10@90. |
|
84 |
v addComponent:((StrokingWrapper on:l) foregroundColor:(Color red)). |
|
85 |
||
86 |
v open. |
|
87 |
[exEnd] |
|
317 | 88 |
" |
286 | 89 |
! ! |
90 |
||
91 |
!LineSegment class methodsFor:'instance creation'! |
|
92 |
||
93 |
from:start to:end |
|
94 |
"return a new lineSegment." |
|
95 |
||
1302 | 96 |
^ self new setStart:start end:end |
286 | 97 |
|
98 |
"Created: 8.5.1996 / 20:40:13 / cg" |
|
282 | 99 |
! |
100 |
||
286 | 101 |
with:p1 with:p2 |
102 |
"return a new lineSegment; the smaller point is taken as startPoint." |
|
282 | 103 |
|
1302 | 104 |
|l| |
105 |
||
106 |
l := self new. |
|
286 | 107 |
p1 < p2 ifTrue:[ |
1302 | 108 |
l setStart:p1 end:p2 |
109 |
] ifFalse:[ |
|
110 |
l setStart:p2 end:p1 |
|
286 | 111 |
]. |
1302 | 112 |
^ l. |
282 | 113 |
|
286 | 114 |
"Created: 8.5.1996 / 20:41:03 / cg" |
282 | 115 |
! ! |
116 |
||
286 | 117 |
!LineSegment methodsFor:'accessing'! |
282 | 118 |
|
119 |
end |
|
120 |
"return the endPoint" |
|
121 |
||
122 |
^ endPoint |
|
123 |
||
286 | 124 |
"Created: 8.5.1996 / 20:41:43 / cg" |
125 |
! |
|
126 |
||
127 |
end:aPoint |
|
128 |
"set the endPoint" |
|
129 |
||
130 |
endPoint := aPoint |
|
131 |
||
132 |
"Created: 8.5.1996 / 20:41:54 / cg" |
|
282 | 133 |
! |
134 |
||
1302 | 135 |
setStart:p1 end:p2 |
136 |
"set both the startPoint and the endPoint" |
|
137 |
||
138 |
startPoint := p1. |
|
139 |
endPoint := p2. |
|
140 |
! |
|
141 |
||
282 | 142 |
start |
143 |
"return the startPoint" |
|
144 |
||
145 |
^ startPoint |
|
146 |
||
286 | 147 |
"Created: 8.5.1996 / 20:41:35 / cg" |
282 | 148 |
! |
149 |
||
286 | 150 |
start:aPoint |
151 |
"set the startPoint" |
|
152 |
||
153 |
startPoint := aPoint |
|
154 |
||
155 |
"Created: 8.5.1996 / 20:42:07 / cg" |
|
156 |
! |
|
157 |
||
158 |
start:p1 end:p2 |
|
2125 | 159 |
<resource: #obsolete> |
1302 | 160 |
"set both the startPoint and the endPoint. |
161 |
Obsolete - use setStart:end: for VW compatibility." |
|
282 | 162 |
|
1302 | 163 |
self obsoleteMethodWarning:'use #setStart:end: for VW compatibility'. |
164 |
self setStart:p1 end:p2. |
|
282 | 165 |
! ! |
166 |
||
287 | 167 |
!LineSegment methodsFor:'comparing'! |
168 |
||
169 |
= aLineSegment |
|
170 |
"return true, if the receiver represents the same lineSegment |
|
171 |
as the argument, aLineSegment" |
|
172 |
||
173 |
aLineSegment species ~~ self species ifTrue:[^ false]. |
|
174 |
^ (startPoint = aLineSegment start |
|
175 |
and:[endPoint = aLineSegment end]) |
|
176 |
||
177 |
"Created: 8.5.1996 / 22:13:02 / cg" |
|
178 |
"Modified: 8.5.1996 / 22:14:34 / cg" |
|
179 |
! |
|
180 |
||
181 |
hash |
|
182 |
"return a number useul for hashing. |
|
183 |
Redefined, since #= is redefined." |
|
184 |
||
185 |
^ (startPoint hash bitShift:12) bitOr:(endPoint hash) |
|
186 |
||
187 |
"Modified: 8.5.1996 / 22:14:12 / cg" |
|
188 |
! ! |
|
189 |
||
286 | 190 |
!LineSegment methodsFor:'converting'! |
191 |
||
192 |
asPointArray |
|
193 |
"return an array containing my points." |
|
194 |
||
195 |
^ Array with:startPoint with:endPoint |
|
196 |
||
197 |
"Created: 8.5.1996 / 20:46:08 / cg" |
|
198 |
! ! |
|
199 |
||
200 |
!LineSegment methodsFor:'displaying'! |
|
282 | 201 |
|
202 |
displayFilledOn:aGC |
|
286 | 203 |
"raise an error - a lineSegment cannot be drawn filled" |
282 | 204 |
|
286 | 205 |
self shouldNotImplement |
282 | 206 |
|
286 | 207 |
"Created: 8.5.1996 / 21:04:27 / cg" |
282 | 208 |
! |
209 |
||
210 |
displayStrokedOn:aGC |
|
286 | 211 |
"display the receiver in the graphicsContext, aGC" |
212 |
||
213 |
aGC displayLineFrom:startPoint to:endPoint |
|
214 |
||
215 |
" |
|
216 |
|v| |
|
282 | 217 |
|
286 | 218 |
v := View new openAndWait. |
282 | 219 |
|
286 | 220 |
(LineSegment from:10@10 to:50@50) displayStrokedOn:v |
221 |
" |
|
222 |
||
223 |
"Modified: 8.5.1996 / 14:40:53 / cg" |
|
224 |
"Created: 8.5.1996 / 21:05:16 / cg" |
|
282 | 225 |
! ! |
226 |
||
1412 | 227 |
!LineSegment methodsFor:'printing'! |
228 |
||
229 |
printOn:aStream |
|
230 |
aStream nextPutAll:'LineSegment from:'. |
|
231 |
startPoint printOn:aStream. |
|
232 |
aStream nextPutAll:' to:'. |
|
233 |
endPoint printOn:aStream. |
|
234 |
! ! |
|
235 |
||
286 | 236 |
!LineSegment methodsFor:'queries'! |
282 | 237 |
|
1412 | 238 |
angle |
2070 | 239 |
"return the receiver's angle (in degrees) in a polar coordinate system. |
240 |
The angle is counted counter-clock-wise, starting with 0 for a horizontal |
|
241 |
line (i.e. 0@0 -> 100@0 has an angle of 0 and 0@0 -> 0@100 has an angle of 90)" |
|
1412 | 242 |
|
2070 | 243 |
^ (endPoint - startPoint) degrees |
1412 | 244 |
|
245 |
" |
|
246 |
(LineSegment from:0@0 to:100@0) angle |
|
2070 | 247 |
(LineSegment from:0@0 to:100@100) angle |
248 |
(LineSegment from:0@0 to:0@100) angle |
|
1412 | 249 |
(LineSegment from:0@0 to:-100@100) angle |
250 |
(LineSegment from:0@0 to:-100@0) angle |
|
251 |
(LineSegment from:0@0 to:-100@-100) angle |
|
252 |
(LineSegment from:0@0 to:0@-100) angle |
|
253 |
" |
|
254 |
! |
|
255 |
||
1547 | 256 |
center |
257 |
^ (startPoint + endPoint) / 2 |
|
1548 | 258 |
|
259 |
" |
|
260 |
(LineSegment from:(10@10) to:(20@10)) center |
|
261 |
(LineSegment from:(10@10) to:(20@20)) center |
|
262 |
" |
|
1547 | 263 |
! |
264 |
||
490
ef43c7a69346
added dummy Scale & InverseScale classVars.
Claus Gittinger <cg@exept.de>
parents:
356
diff
changeset
|
265 |
computeBounds |
282 | 266 |
"return the smallest enclosing rectangle" |
267 |
||
356 | 268 |
|x y minX maxX minY maxY| |
282 | 269 |
|
356 | 270 |
minX := maxX := startPoint x. |
271 |
x := endPoint x. |
|
272 |
minX := minX min:x. |
|
273 |
maxX := maxX max:x. |
|
274 |
||
275 |
minY := maxY := startPoint y. |
|
276 |
y := endPoint y. |
|
277 |
minY := minY min:y. |
|
278 |
maxY := maxY max:y. |
|
286 | 279 |
|
280 |
^ Rectangle left:minX right:maxX top:minY bottom:maxY |
|
282 | 281 |
|
282 |
" |
|
286 | 283 |
(LineSegment from:(10@10) to:(90@90)) bounds |
282 | 284 |
" |
285 |
||
356 | 286 |
"Modified: 26.5.1996 / 13:06:55 / cg" |
490
ef43c7a69346
added dummy Scale & InverseScale classVars.
Claus Gittinger <cg@exept.de>
parents:
356
diff
changeset
|
287 |
"Created: 12.2.1997 / 11:43:50 / cg" |
1302 | 288 |
! |
289 |
||
2152 | 290 |
dist:aPoint |
2151 | 291 |
"the distance of aPoint to this segment" |
292 |
||
2152 | 293 |
|u v px py ax ay bx by| |
2151 | 294 |
|
2152 | 295 |
ax := startPoint x. |
296 |
ay := startPoint y. |
|
297 |
bx := endPoint x. |
|
298 |
by := endPoint y. |
|
299 |
px := aPoint x. |
|
300 |
py := aPoint y. |
|
2151 | 301 |
|
2152 | 302 |
u := aPoint - startPoint. |
303 |
v := endPoint - startPoint. |
|
2151 | 304 |
((u x * v x) + (u y * v y)) < 0 ifTrue:[ |
2152 | 305 |
^ "(startPoint dist:aPoint)" (( px - ax) squared + (py - ay) squared) sqrt |
2151 | 306 |
]. |
307 |
||
2152 | 308 |
u := aPoint - endPoint. |
2151 | 309 |
v := v negated. |
310 |
((u x * v x) + (u y * v y)) < 0 ifTrue:[ |
|
2152 | 311 |
^ "(endPoint dist:aPoint)" (( px - bx) squared + (py - by) squared) sqrt |
2151 | 312 |
]. |
313 |
||
314 |
^( (( px * ( ay - by )) + (py * ( bx - ax )) + ( (ax * by) - (bx * ay) ) ) |
|
315 |
/ ( ( bx - ax )squared + ( by - ay )squared ) sqrt ) abs |
|
316 |
||
317 |
" |
|
318 |
(LineSegment from:(0@0) to:(10@10)) dist:0@0 |
|
319 |
(LineSegment from:(0@0) to:(10@10)) dist:10@10 |
|
2152 | 320 |
(LineSegment from:(0@0) to:(10@10)) dist:11@10 |
2151 | 321 |
(LineSegment from:(0@0) to:(10@10)) dist:-1@-1 |
322 |
(LineSegment from:(0@0) to:(10@10)) dist:5@5 |
|
323 |
(LineSegment from:(0@0) to:(10@10)) dist:6@4 |
|
324 |
(LineSegment from:(0@0) to:(10@10)) dist:5@0 |
|
325 |
" |
|
326 |
! |
|
327 |
||
1546 | 328 |
isHorizontal |
329 |
"return true, if I am a horizontal line" |
|
330 |
||
331 |
^ startPoint y = endPoint y |
|
332 |
! |
|
333 |
||
334 |
isVertical |
|
335 |
"return true, if I am a vertical line" |
|
336 |
||
337 |
^ startPoint x = endPoint x |
|
338 |
! |
|
339 |
||
1302 | 340 |
length |
341 |
"return the length of the vector" |
|
342 |
||
343 |
^ startPoint dist:endPoint |
|
282 | 344 |
! ! |
345 |
||
764 | 346 |
!LineSegment methodsFor:'testing'! |
347 |
||
348 |
isLineSegment |
|
349 |
"return true, if the receiver is a line segment" |
|
350 |
||
351 |
^ true |
|
352 |
||
353 |
||
354 |
! ! |
|
355 |
||
1302 | 356 |
!LineSegment methodsFor:'transforming'! |
357 |
||
358 |
scaledBy:amount |
|
359 |
^ self species |
|
360 |
from:(startPoint scaledBy:amount) |
|
361 |
to:(endPoint scaledBy:amount) |
|
362 |
! |
|
363 |
||
364 |
translatedBy:amount |
|
365 |
^ self species |
|
366 |
from:(startPoint translatedBy:amount) |
|
367 |
to:(endPoint translatedBy:amount) |
|
368 |
! ! |
|
369 |
||
286 | 370 |
!LineSegment class methodsFor:'documentation'! |
282 | 371 |
|
372 |
version |
|
2152 | 373 |
^ '$Header: /cvs/stx/stx/libbasic2/LineSegment.st,v 1.21 2009-06-06 10:07:44 cg Exp $' |
282 | 374 |
! ! |