Skip to content

Instantly share code, notes, and snippets.

@lianera
Created February 3, 2016 15:04
Show Gist options
  • Save lianera/58e3fbbd068af8eb02a0 to your computer and use it in GitHub Desktop.
Save lianera/58e3fbbd068af8eb02a0 to your computer and use it in GitHub Desktop.
A cross-sectional view of ocean simulation. See http://lianera.com/cg/2016/01/29/OceanSectional.html
clear;
width=100;
height=100;
snum=5;
xi=rand(snum,1)*width;
yi=rand(snum,1)*height;
fhi=rand(snum,1)*2*pi;
Ai=rand(snum,1)*0.3;
frei=rand(snum,1)*0.1;
lambda=10;
sg = zeros(height,width);
figure
loops = 100;
F(loops) = struct('cdata',[],'colormap',[]);
for t=1:loops
for y=1:height
for x=1:width
xt=ones(snum,1)*x;
yt=ones(snum,1)*y;
sg(y,x)=sum(Ai.*sin(2*pi*(frei*t-sqrt((xt-xi).*(xt-xi)+(yt-yi).*(yt-yi))/lambda)+fhi));
end
end
surf(sg)
axis([0,width,0,height,-10,10]);
drawnow
F(t) = getframe(gcf);
end
fig = figure;
movie(fig,F,1)
clear;
width=100;
height=100;
snum=30;
xi=rand(snum,1)*width;
yi=rand(snum,1)*height;
fhi=rand(snum,1)*2*pi;
Ai=rand(snum,1)*0.2;
frei=rand(snum,1)*0.02;
lambda=40;
fnum=50;
sg = zeros(width,fnum);
fgy = (1:fnum)'*2;
colors=[linspace(0.8,0.2,fnum)' linspace(0.8,0.2,fnum)' linspace(0.8,0.2,fnum)'];
fig=figure('Position', [100, 100, 800, 600]);
loops = 100;
F(loops) = struct('cdata',[],'colormap',[]);
for t=1:loops
for x=1:width
xt=ones(snum,1)*x;
for f=1:fnum
sg(x,f)=sum(Ai.*sin(2*pi*(frei*t-sqrt((xt-xi).*(xt-xi)+(fgy(f)-yi).*(fgy(f)-yi))/lambda)+fhi));
end
end
clf
p=plot(sg);
set(p, {'color'}, num2cell(colors, 2));
axis([0,width,-5,5]);
drawnow
F(t) = getframe(gcf);
end
movie(fig,F,1);
v = VideoWriter('out.avi');
open(v);
writeVideo(v,F);
close(v);
<canvas id="wave" width="1000" height="600"></canvas>
<canvas id="topview"></canvas>
<style type="text/css">
#wave{
width: 1000px;
height: 600px;
/*border: 1px dotted gray;*/
display: block;
}
</style>
<script type="text/javascript">
var waveSourcePoints;
var waveTargetPoints;
var rangeWidth = 1000;
var rangeHeight = 600;
/**
* @brief function of water transform model
* @param t target
* @param s source
* @param time time
*/
function fnWave(t, s, time){
var lambda = 400;
z = s.a * Math.sin(2 * Math.PI *
(s.freq * time -
Math.sqrt((t.x - s.x) * (t.x - s.x) + (t.y - s.y) * (t.y - s.y)) / lambda)
+ s.phi);
return z;
}
/**
* @brief generate wave sources
* @param num number of sources
*/
function genWaveSource(num){
var sources = new Array(num);
for (var i = 0; i < num; i++) {
s = new Object();
s.a = 50 * Math.random();
s.phi = 2 * Math.PI * Math.random();
s.freq = 0.3 * Math.random();
s.x = rangeWidth * Math.random();
s.y = rangeHeight * Math.random();
sources[i] = s;
};
return sources;
}
/**
* @brief sample points from xy plane
* @param num number of target points
*/
function sampleTarget(num){
var targets = new Array(num);
for( var i = 0; i < num; i++){
t = new Object();
t.x = rangeWidth * Math.random();
t.y = rangeHeight * Math.random();
t.z = 0;
targets[i] = t;
}
return targets;
}
/**
* @brief multi sources works on a target
* @param t target
* @param sources the array of sources
* @param time time
*/
function fnMultiSourceWave(t, sources, time){
var zAcc = 0;
for(var i = 0; i < sources.length; i++){
s = sources[i];
z = fnWave(t, s, time);
zAcc += z;
}
return zAcc;
}
/**
* @brief calculate the surface of water, currently a line of water surface
* @param sources the array of sources
* @param time time
*/
function calcWaveSurface(sources,targets, time){
for( var i = 0; i < targets.length; i++){
t = targets[i];
t.z = fnMultiSourceWave(t, sources, time);
}
}
/**
* @brief draw the wave
*/
function drawWave(){
var date = new Date();
var seconds = date.getSeconds() + date.getMilliseconds() / 1000;
sources = waveSourcePoints;
targets = waveTargetPoints;
calcWaveSurface(sources, targets, seconds);
var waveCanvas = document.getElementById("wave");
var ctx = waveCanvas.getContext("2d");
var width = waveCanvas.width;
var height = waveCanvas.height;
// clear the canvas
ctx.fillStyle = 'rgba(0,0,0,10)';
//ctx.clearRect(0,0,width,height);
ctx.fillRect(0,0,width,height);
for(var i = targets.length - 1; i >= 0; i--){
p = targets[i];
//ctx.lineTo(p.x, p.z + waveCanvas.height/2);
//ctx.drawImage(particle, p.x, p.z + height / 2);
//ctx.arc(p.x, p.z + height / 2,5, 0,Math.PI*2,true);
d = 1500 / (300 + p.y);
var intensity = 100 / (100 + p.y);
//intensity = 1;
if(intensity > 1)
intensity = 1;
ctx.fillStyle="rgba(" + Math.floor(255*intensity) + "," +
Math.floor(255*intensity) + "," +
Math.floor(255*intensity) + ", 255)";
ctx.fillRect(p.x, p.z + height / 2,d,d);
}
ctx.fill();
window.requestAnimationFrame(drawWave);
}
function init(){
waveSourcePoints = genWaveSource(10);
waveTargetPoints = sampleTarget(1000);
window.requestAnimationFrame(drawWave);
}
init();
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment