Looking at Curl through Particle Simulation
In this demonstration (below) you can see the curl of the given function shown as the colour of the particles.
The source code is below:
raw file
var scene, camera, renderer, clock, tick // define world attributes as globals
var vel_funct, curl_funct, geometry, material, body, options // some throwaway variables ( for short term use )
// THE FUNCTION(s)
// ........ Edit Here to Change the Function
// ........ to avoid writing a parser / something that differentiates functions
// ........ the curl_funct should be equal to curl( vel_funct ), to change that you'll have to
// ........ calculate the function using 2dCurl( r ) = ( r.y )dx - ( r.x )dy
vel_funct = ( r ) => new THREE.Vector3( Math.sin( r.y ), Math.pow( r.x, 3 ), 0 ).multiplyScalar( 0.1 )
curl_funct = ( r ) => 3 * Math.pow( r.x, 2 ) - Math.cos( r.y )
// vel_funct = ( r ) => new THREE.Vector3( Math.sin( r.y * 5 ), 0, 0 )
// curl_funct = ( r ) => - 5 * Math.cos( r.y * 5 )
// vel_funct = ( r ) => new THREE.Vector3( -r.x, -r.y, 0 )
// curl_funct = ( r ) => 0
function build() {
// SCENE
scene = new THREE.Scene()
//CLOCK
clock = new THREE.Clock()
tick = 0
// CAMERA
camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 )
camera.position.z = 2
// RENDERER
renderer = new THREE.WebGLRenderer()
renderer.setSize( window.innerWidth, window.innerHeight )
document.body.appendChild( renderer.domElement )
// PARTICLES
particleSystem = new THREE.GPUParticleSystem( { maxParticles: 500000 } );
scene.add( particleSystem )
particleHandler = new ParticleHandler( vel_funct, curl_funct, 20, 0.1, 500000 )
}
function animate() {
requestAnimationFrame( animate )
particleHandler.tick()
renderer.render( scene, camera )
}
class ParticleHandler {
constructor( vel_funct, curl_funct, range, timeScale, spawnRate ) {
options = {
position: new THREE.Vector3(),
positionRandomness: 0.1,
velocity: new THREE.Vector3(),
velocityRandomness: 0,
color: 0xaa0000,
colorRandomness: 0.5,
turbulence: 0,
lifetime: 1.5,
size: 6,
sizeRandomness: 10
}
this.timeScale = timeScale
this.spawnRate = spawnRate
this.range = range
this.vel_funct = vel_funct
this.curl_funct = curl_funct
}
tick() {
var delta = clock.getDelta() * this.timeScale;
tick += delta;
if ( tick < 0 ) { tick = 0 };
if ( delta > 0 ) {
for ( var x = 0; x < this.spawnRate * delta; x++ ) {
options.position.x = ( Math.random( ) * this.range ) - this.range / 2
options.position.y = ( Math.random( ) * this.range ) - this.range / 2
options.velocity = this.vel_funct( options.position )
options.color = new THREE.Color( 0xaaaaaa ).add( new THREE.Color( 0xff0000 ).multiplyScalar( this.curl_funct( options.position ) ) )
particleSystem.spawnParticle( options )
}
}
particleSystem.update( tick )
}
}
build()
animate()