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. Atitit.随时间变色特效 ---包厢管理系统的规划

    Atitit.随时间变色特效 ---包厢管理系统的规划 1 流程滴定仪 定义的参数 颜色.位置(开始值,结束值,当前比值) >>返回数值 可以后期处理转成双位16进制码 分别定义复合颜色的 ...

  2. [求助] 关于DDR3的读写操作,看看我的流程对吗?

    [求助] 关于DDR3的读写操作,看看我的流程对吗? 最近简单调了一下KC705开发板上面的DDR3,型号是MT8JTF12864HZ-1G6:有时候加载程序后,发现读出数据不是写进去的,在这将我的操 ...

  3. Github上Fork代码,及源码修改

    iOS开发中经常遇到这种情况,你使用的第三方库不能完全满足自己项目需要,只能修改源码来解决. 我们以前的解决办法是,添加到项目中直接修改源码.这样就有一个问题,不能和源库同步,当作者更新后你不能(po ...

  4. C++ STL标准模板库(stack)

    //stack的使用 #define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<stack> using name ...

  5. 极光Java后台推送APP对接

    1.极光对接,首先需要注册用户,和创建应用 2,.Java对接需要依赖包 <dependency> <groupId>cn.jpush.api</groupId> ...

  6. VS2012使用正则删除空行

    1:Ctrl + H 打开快速替换窗口 2:输入:^\s\S*$\n 3:点击使用正则替换的选项

  7. Java实现验证码的制作

    验证码概述 为什么使用验证码? 验证码(CAPTCHA)是一种全自动程序.主要是为了区分“进行操作的是不是人”.如果没有验证码机制,将会导致以下的问题: 对特定网站不断进行登录,破解密码: 对某个网站 ...

  8. ubuntu text mode和图形界面切换

    Ctrl+Alt+F1(或者F2~F6总共可以同时开6个text mode界面并行工作) Ctrl+Alt+F7切换到图形界面

  9. PARSEC測试集的应用领域和working set的大小

    參考:tp=&arnumber=4636090">PARSEC vs. SPLASH-2: A Quantitative Comparison of Two Multithre ...

  10. [Hadoop]安装

    1 从官网下载hadoop稳定版 http://www.apache.org/dyn/closer.cgi/hadoop/common/ 2 安装JAVA 参考如下blog http://www.cn ...