64 lines
1.6 KiB
Smalltalk
64 lines
1.6 KiB
Smalltalk
Point3D :=
|
|
Point subclass:#Point3D
|
|
instanceVariableNames:'z'
|
|
classVariableNames:''
|
|
poolDictionaries:''
|
|
category:''
|
|
inEnvironment:nil.
|
|
|
|
Point3D compile:'z ^ z'.
|
|
Point3D compile:'z:v z := v'.
|
|
|
|
normalize := [:v | |invLen|
|
|
invLen := 1 / (dot value:v value:v) sqrt.
|
|
v x: v x * invLen.
|
|
v y: v y * invLen.
|
|
v z: v z * invLen.
|
|
].
|
|
|
|
dot := [:a :b |
|
|
(a x * b x) + (a y * b y) + (a z * b z)
|
|
].
|
|
|
|
drawSphere := [:r :k :amb :dir |
|
|
|w h imh vec img|
|
|
|
|
w := r*4. h := r*3.
|
|
img := Image width:w height:h depth:8.
|
|
img photometric:#blackIs0; createPixelStore.
|
|
vec := Point3D new.
|
|
0-r to:r do:[:x |
|
|
0-r to:r do:[:y |
|
|
|z s lum|
|
|
(z := (r*r) - (x*x) - (y*y)) >= 0 ifTrue:[
|
|
vec x: x.
|
|
vec y: y.
|
|
vec z: z sqrt.
|
|
normalize value:vec.
|
|
s := dot value:dir value:vec.
|
|
s < 0 ifTrue:[ s := 0 ].
|
|
lum := 255 * ((s raisedTo: k) + amb) / (1 + amb).
|
|
lum < 0 ifTrue:[
|
|
lum := 0
|
|
] ifFalse:[ lum > 255 ifTrue:[
|
|
lum := 255
|
|
]].
|
|
img atX:(x+(w//2)) y:(y+(h//2)) put:(Color greyByte:lum).
|
|
]
|
|
]
|
|
].
|
|
img
|
|
].
|
|
|
|
main := [
|
|
|dir img|
|
|
|
|
dir := Point3D new x:-30; y:-30; z:50; yourself.
|
|
normalize value:dir.
|
|
img := drawSphere value: 100 value: 1.5 value: 0.2 value: dir.
|
|
img displayOn:(View new extent:400@400; openAndWait).
|
|
img saveOn:'sphere.png'.
|
|
].
|
|
|
|
main value.
|