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(很美)的更多相关文章

  1. css3很美的蟠桃动画

    查看效果:http://hovertree.com/texiao/css3/26/ 源码下载:http://hovertree.com/h/bjaf/ndhxgfkn.htm 效果图如下: 代码如下: ...

  2. x01.os.15: 看上去很美

    张碧晨在韩国学的不是技巧,而是基本功:气息!声音由气息托着,似真声而不是真声,似假声又不是假声,所以才能在动听的地方唱得更动听.编程也是一样,基本功很重要:内存!所谓的黑客高手,攻击的一大手段,便是利 ...

  3. StoryBoard--看上去很美

    StoryBoard--看上去很美 介绍 StoryBoard 是苹果在 2011 年的 WWDC Session 309<Introducing Interface Builder Story ...

  4. 看上去很美 国内CDN现状与美国对比

    CDN的理想与现实 多年以前,当<Kingdom of Heaven>这部史诗电影发行的时候,中国的影迷使用电驴和BT来寻找种子,而那个时候,高清也才刚刚进入电影领域,我的同事不惜用自家的 ...

  5. oracle 11G direct path read 很美也很伤人

    direct path read在11g中,全表扫描可能使用direct path read方式,绕过buffer cache,这样的全表扫描就是物理读了. 在10g中,都是通过gc buffer来读 ...

  6. 听起来很美,用起来很累!停车类APP软肋在哪

    据数据显示,全国现有汽车已达1亿7千万辆,停车位缺于6800万个.而在北京,汽车保有量和车位的配比大约是1:0.5,而国际上一般是1:1.2,结构严重失衡.正所谓哪里有需求,哪里就有市场.停车位的走俏 ...

  7. Visualizing mathematical functions by generating custom meshes using FireMonkey(很美)

    Abstract: This article discusses how you can generate your own 3-dimensional mesh for visualizing ma ...

  8. MacBook USB Type-C接口很美?其实是缩水的!

    苹果终于推出了12寸的全新MacBook,拥有2304×1440的高分辨率.蝶式结构全尺寸键盘.新的触摸板.14nm Core M处理器和无风扇设计,以及新的USB 3.1 Type-C接口.可以预料 ...

  9. 微信小程序看上去很美

    目前不少关于 微信小程序 的文章主要集中在两各方面:一是开发技术细节:二是怎么靠此赚钱. -- “微信小程序”所处的环境 -- 2016年初,美国号召全民学编程,包括监狱服刑人员.同样,在中国要想掌握 ...

随机推荐

  1. 有关linux磁盘分区优化

    Linux中几个重要的目录,这几个目录在ubuntu安装的硬盘分区时,可选择性的特别分区,进行挂载./usr 文件系统中一般不改变的文件,如库,程序./var 文件系统包含会改变的文件./home 文 ...

  2. redis命令_SETNX

    SETNX key value 将 key 的值设为 value ,当且仅当 key 不存在. 若给定的 key 已经存在,则 SETNX 不做任何动作. SETNX 是『SET if Not eXi ...

  3. [转]C/C++中volatile关键字详解

    http://www.cnblogs.com/yc_sunniwell/archive/2010/07/14/1777432.html

  4. linux学习笔记20--命令df和dh,fdisk

    df和dh是用来查看磁盘空间使用情况的. linux中df命令的功能是用来检查linux服务器的文件系统的磁盘空间占用情况.可以利用该命令来获取硬盘被占用了多少空间,目前还剩下多少空间等信息. 1.命 ...

  5. Effective Java学习笔记--创建和销毁对象

    创建和销毁对象 一.静态工厂方法代替构造器 静态工厂方法的优缺点 优点: 1.可以自定义名称(可以将功能表述的更加清晰) 2.不必每次调用都创建新的对象(同一对象重复使用) 3.返回的类型可以是原返回 ...

  6. Unix系统编程()main函数的命令行参数

    命令行参数输入双引号是什么效果? 好像可以去空格化.

  7. PHP——上传头像(2)

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  8. C# 个人疏漏整理

    1.dynamic和var不能混为一谈. var声明局部变量只是一种简化语法,var要求编译器根据之后的表达式推断具体的数据类型. var只能用于声明方法内部的局部变量,dynamic则可用于局部变量 ...

  9. eclipse JavaEE版"javax.servlet.http.HttpServlet" was not found on the Java Build Path问题的解决办法

    使用eclipse JavaEE 版,新建 Dynamic Web Project 项目.在项目里添加 JSP 文件,会在文件头部出现错误提示.提示语句为:The superclass "j ...

  10. EasyUI项目学习

    介绍easyui的使用,主要包括以下组件 布局面板 - layout 可伸缩面板 - accordion 选项卡 - tabs 控制面板 - panel 窗口 - window 对话框 - dialo ...