# Prerequisites!

This article builds on my previous article "Visualizing mathematical functions by generating custom meshes using FireMonkey".

# The wave function

The wave function we'll use in this article is:

f(x,y) = A*sin(1/L*r-v*t)

where:

- (x,y) = observation point
- A = amplitude
- L = wave length
- r = distance between wave center and observation point
- v = velocity of wave propagation
- t = time

In Delphi it simply becomes:

`function`

f(x,y : Double) : Double;`begin`

f := Amplitude*Sin(1/Length*Sqrt(Sqr(x-PosX)+Sqr(y-PosY))-Speed*t);`end`

;

*Note: It should be noted that this function simply gives us the state of equilibrium. We're completely ignoring starting scenarios and the fact that waves die out over time and distance.*

The screen shot below shows one wave:

# **Hide image**

# Generating the mesh

In order to generate the mesh, we borrow the code from my previous article, and modify it slightly to give it a time parameter:

`procedure`

TForm1.GenerateWave(t : Double);`function`

f(x,y : Double) : Double;`var`

i : Integer;`begin`

Result := 0;`for`

i:=0`to`

3`do`

`with`

Wave[i]`do`

`if`

Enabled`then`

Result := Result+Amplitude*Sin(1/Length*Sqrt(Sqr(x-PosX)+Sqr(y-PosY))-Speed*t);`end`

;`const`

MaxX = 30; MaxZ = 30;`var`

u, v : Double; px, py, pz :`array`

[0..3]`of`

Double; d : Double; NP, NI : Integer; BMP : TBitmap; k : Integer;`begin`

d := 0.5; NP := 0; NI := 0; Mesh1.Data.VertexBuffer.Length := Round(2*MaxX*2*MaxZ/d/d)*4; Mesh1.Data.IndexBuffer.Length := Round(2*MaxX*2*MaxZ/d/d)*6; BMP := TBitmap.Create(1,360);`for`

k := 0`to`

359`do`

BMP.Pixels[0,k] := CorrectColor(HSLtoRGB(k/360,0.75,0.5)); u := -MaxX;`while`

u < MaxX`do`

`begin`

v := -MaxZ;`while`

v < MaxZ`do`

`begin`

px[0] := u; pz[0] := v; py[0] := f(px[0],pz[0]); px[1] := u+d; pz[1] := v; py[1] := f(px[1],pz[1]); px[2] := u+d; pz[2] := v+d; py[2] := f(px[2],pz[2]); px[3] := u; pz[3] := v+d; py[3] := f(px[3],pz[3]);`with`

Mesh1.Data`do`

`begin`

`// Set the points`

`with`

VertexBuffer`do`

`begin`

Vertices[NP+0] := Point3D(px[0],py[0],pz[0]); Vertices[NP+1] := Point3D(px[1],py[1],pz[1]); Vertices[NP+2] := Point3D(px[2],py[2],pz[2]); Vertices[NP+3] := Point3D(px[3],py[3],pz[3]);`end`

;`// Map the colors`

`with`

VertexBuffer`do`

`begin`

TexCoord0[NP+0] := PointF(0,(py[0]+35)/45); TexCoord0[NP+1] := PointF(0,(py[1]+35)/45); TexCoord0[NP+2] := PointF(0,(py[2]+35)/45); TexCoord0[NP+3] := PointF(0,(py[3]+35)/45);`end`

;`// Map the triangles`

IndexBuffer[NI+0] := NP+1; IndexBuffer[NI+1] := NP+2; IndexBuffer[NI+2] := NP+3; IndexBuffer[NI+3] := NP+3; IndexBuffer[NI+4] := NP+0; IndexBuffer[NI+5] := NP+1;`end`

; NP := NP+4; NI := NI+6; v := v+d;`end`

; u := u+d;`end`

; Mesh1.Material.Texture := BMP;`end`

;

# Animating the mesh

The above code generates a "snap shot" of the wave interaction between 4 waves at any time *t*.

Animating the wave is simply a matter of using a timer to increment time and re-generating the mesh over and over again:

`procedure`

TForm1.Timer1Timer(Sender: TObject);`begin`

GenerateWave(t); t := t+0.1;`end`

;

The waves are represented by this record:

`type`

TWave =`record`

Enabled : Boolean; Amplitude : Double; Length : Double; PosX : Double; PosY : Double; Speed : Double;`end`

;

In the demo project that accompanies this article, I have declared 4 starting waves like so:

`var`

Wave :`array`

[0..3]`of`

TWave = ((Enabled: False; Amplitude: 1; Length: 1; PosX: -20; PosY: -20; Speed: 1), (Enabled: False; Amplitude: 1; Length: 1; PosX: +20; PosY: -20; Speed: 1), (Enabled: False; Amplitude: 1; Length: 1; PosX: +20; PosY: +20; Speed: 1), (Enabled: False; Amplitude: 1; Length: 1; PosX: -20; PosY: +20; Speed: 1));

Note that all 4 waves have the same properties, except that their origins are spread across the coordinate system. Specifically they're located in (-20,-20), (+20,-20), (+20,+20) and (-20,+20).

# Demo application

You can find my demo application in CodeCentral.

# Contact

Please feel free to email me with feedback to aohlsson at embarcadero dot com.

## Latest Comments View All Add New RSS ATOM

Move mouse over comment to see the full text