### Class SurfaceWave

Smalltalk
Building a Wave Viewer

Wilf LaLonde
Listing 1. Class SurfaceWave.

``````
class:									SurfaceWave
superclass:							Object
instance variables:			grid functionIndex
class variables:				SpaceWavelength

class methods

initializing
initialize
"SurfaceWave initialize"
self spaceWavelength: 2.0; timeWavelength: 1.0.
self amplitude: 0.05

wavelength/amplitude
spaceWavelength: aNumber
SpaceWavelength := aNumber.
* Float pi * 2.0

spaceWavelength
^SpaceWavelength

timeWavelength: milliseconds
TimeWavelength := milliseconds.
* 0.001 * Float pi * 2.0

timeWavelength
^TimeWavelength

wave functions
function1ForPoint: aPoint time: time
"Wave in the x direction."

function2ForPoint: aPoint time: time
"Wave in the z direction."

function3ForPoint: aPoint time: time
"Wave in the x-z diagonal direction."
radians := ((aPoint x + aPoint z)

function4ForPoint: aPoint time: time
"Wave in the x-z diagonal direction from the center."
radians := ((aPoint x abs + aPoint z abs)

function5ForPoint: aPoint time: time
"Wave in the x-z diagonal direction from the
center growing larger outward."
radians := ((aPoint x abs + aPoint z abs) squared

function6ForPoint: aPoint time: time
"Wave in the x-z diagonal direction off-center."
radians := (((aPoint x - 0.25) abs + (aPoint z - 0.25) abs)

instance methods

initializing
initialize
self initializeGrid.
self functionIndex: 1

initializeGrid
| scale |
scale := ([email protected]) / self extent. "For x and z"
1 to: self extent x do: [:x |
1 to: self extent y do: [:y |
self at: x@y put:
(Point3D x: x*scale x - 0.5 y: 0.0 z: y*scale y - 0.5)]].

get/set
extent: aPoint
grid := (1 to: aPoint x) collect: [:x | Array new: aPoint y].
self initialize

extent
"The grid is an array (1 per x value)
of arrays (1 per z value))."
^grid size@grid first size

functionIndex
^functionIndex

functionIndex: anInteger
functionIndex := anInteger

functionName
^('function', self functionIndex printString,
'ForPoint:time:') asSymbol.

2D access
at: aPoint
^(grid at: aPoint x) at: aPoint y
at: aPoint put: aPoint3D
^(grid at: aPoint x) at: aPoint y put: aPoint3D

ticking
self functionIndex: self functionIndex + 1.
(self class respondsTo: self functionName)
ifFalse: [self functionIndex: 1] "wrap"

tick: time
| selector aPoint3D |
selector := self functionName.
1 to: self extent x do: [:x |
1 to: self extent y do: [:y |
aPoint3D := self at: x@y.
aPoint3D y: (self class
perform: selector with: aPoint3D with: time)]].

drawing
draw
| x1 x2 y1 y2 |
"Draw the x lines in red."
1 to: self extent y do: [:y |
x1 := self at: 1@y.
2 to: self extent x do: [:x |
x2 := self at: x@y.
CanvasLibrary
drawLineFrom: x1 x and: x1 y and: x1 z
to: x2 x and: x2 y and: x2 z
color: 1.0 and: 0.0 and: 0.0 thickness: 2.
x1 := x2]].

"Draw the z lines in green."
1 to: self extent x do: [:x |
y1 := self at: x@1.
2 to: self extent y do: [:y |
y2 := self at: x@y.
CanvasLibrary
drawLineFrom: y1 x and: y1 y and: y1 z
to: y2 x and: y2 y and: y2 z
color: 0.0 and: 1.0 and: 0.0 thickness: 2.
y1 := y2]]
``````

Wilf LaLonde is director of Learning Dimensions, Inc., a company focused on 3D gaming development.