Visualizing wave interference using FireMonkey(很美)

Posted findumars

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Visualizing wave interference using FireMonkey(很美)相关的知识,希望对你有一定的参考价值。

 

Visualizing wave interference using FireMonkey

By: Anders Ohlsson

Abstract: This article discusses how you can generate your own dynamic 3-dimensional mesh for visualizing wave interference using Delphi XE2 and FireMonkey.

    Prerequisites!

    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技术分享图片

Two waves interfering with each other:

Hide image
技术分享图片

And 4 waves while we‘re at it:

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.

 

http://edn.embarcadero.com/article/42012

以上是关于Visualizing wave interference using FireMonkey(很美)的主要内容,如果未能解决你的问题,请参考以下文章

Visualizing and Understanding Convolutional Networks

Lecture 12: Visualizing and Understanding

Visualizing and Understanding Convolutional Networks论文复现笔记

R TUTORIAL: VISUALIZING MULTIVARIATE RELATIONSHIPS IN LARGE DATASETS

maven之可视化项目依赖(Visualizing dependencies)

Python可视化(matplotlib)图像之误差可视化(Visualizing Errors)