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.减少http请求数方案

    Atitit.减少http请求数方案 1. 原理与方法1 1.1. -------jsp1 1.2. "index/js.txt";2 1.3. connReduceDync2 1 ...

  2. Atitit.增强系统稳定性----虚拟内存的设置

    Atitit.增强系统稳定性----虚拟内存的设置 1.1. 读取虚拟内存配置1 1.2. 禁止虚拟内存1 1.3. 默认所有驱动器虚拟内存1 1.4. 设置c d盘虚拟内存为系统管理1 1.5. 设 ...

  3. codeForces 574b Bear and Three Musketeers

    一种巧妙到暴力方式,这题到抽象化:在一个无向图中,找一个度数和最小到三阶到圈. 首先对边进行枚举,这样确定了两个顶点,然后在对点进行枚举,找到一个可以构成三元圈到点,则计算他们到度数和. 最后保存最小 ...

  4. GCD 莫比乌斯反演 给定整数N,求1<=x,y<=N且Gcd(x,y)为素数的 数对(x,y)有多少对.

    /** 题目:GCD 链接:https://vjudge.net/contest/178455#problem/E 题意:给定整数N,求1<=x,y<=N且Gcd(x,y)为素数的 数对( ...

  5. Linux下配置Hadoop全分布式环境

    1. 前提 部署全分布式环境,我们肯定不能在一台服务器上了,这里我用了7台服务器,在VMware上开了7个虚拟机,如下图所示: 我基本配置了一晚上才搞定,第一次配置一般都有错,这时候不妨去到hadoo ...

  6. Supervisord进程管理工具

    进程管理工具Supervisord Posted on 2014/06/17 by admin Supervisord 上面已经介绍了Go目前是有两种方案来实现他的daemon,但是官方本身还不支持这 ...

  7. python判断字符串是否为空的方法s.strip()=='' if not s.strip():

    python 判断字符串是否为空用什么方法? 复制代码 s=' ' if s.strip()=='':     print 's is null' 或者 if not s.strip():     p ...

  8. react+echarts/g2/bizcharts可视化图表

    一.echarts的折线图的使用demo如下,linecharts为实例化的封装组件,line为实际应用的组件 cnpm install echarts import React from 'reac ...

  9. Java 设计模式01 - 简单工厂模式

    先要学习设计模式之前的先看看一些基础 UML类图简单说明 可以先看看我的这篇博客: UML类图简单说明,学习编程思路的必会技能 接下来才是重点,开始我们的旅程吧. 一.UML类图展示 我们要用简单工厂 ...

  10. 修改net基本三层 动软生产

    控制层(dal) 模型层-实体类(Model) 显示层-web