Skip to content

Instantly share code, notes, and snippets.

@AdmiralPotato
Created May 31, 2013 01:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AdmiralPotato/5682387 to your computer and use it in GitHub Desktop.
Save AdmiralPotato/5682387 to your computer and use it in GitHub Desktop.
First stab at a multiple force-field particle system
var n = NPos3d,
scene = new n.Scene({
globalCompositeOperation: 'lighter'
}),
particleList = [],
forceList = [];
var Particle = function(args){
var t = this;
args = args || {};
n.blessWith3DBase(t, args);
t.index = particleList.length;
t.vel = args.vel || [0,0,0];
particleList.push(t);
};
Particle.prototype = {
shape: new n.Geom.Circle({
segments: 3,
radius: 3
}),
update: function(){
var t = this;
t.pos[0] += t.vel[0];
t.pos[1] += t.vel[1];
t.pos[2] += t.vel[2];
t.rot[2] = Math.atan2(t.vel[1], t.vel[0]);
t.color = 'hsl(' + t.getHueFromVelocity() + ', 100%, 50%)';
t.warpToCenter();
t.render();
},
warpToCenter: function(){
var t = this;
if(
Math.abs(t.pos[0]) > scene.cx ||
Math.abs(t.pos[1]) > scene.cy
){
t.pos[0] = t.pos[1] = 0;
}
},
getHueFromVelocity: function(){
var t = this,
h = (Math.atan2(t.vel[1], -t.vel[0]) + pi) / deg,
rounded = Math.round(h * 100) / 100;
if(t.index === 0){
//console.log(h, rounded);
}
return rounded;
}
};
var forceShape = new n.Geom.Sphere({
radius: 1,
order: "xyz"
}),
fr = 0.1,
fspl = forceShape.points.length,
fslc = '#fff';
forceShape.points.push(
[fr * cos( 0 ), fr * sin( 0 ), 0],
[fr * cos(120 * deg), fr * sin(120 * deg), 0],
[fr * cos(240 * deg), fr * sin(240 * deg), 0]
);
forceShape.lines.push(
[fspl , fspl + 1, fslc],
[fspl + 1, fspl + 2, fslc],
[fspl + 2, fspl , fslc]
);
var Force = function(args){
var t = this;
args = args || {};
n.blessWith3DBase(t, args);
t.index = forceList.length;
t.radius = args.radius || 80;
t.phaze = 0;
t.charge = args.charge !== undefined ? args.charge : 1;
forceList.push(t);
};
Force.prototype = {
color: 'rgba(191,0,255,0.2)',
shape: forceShape,
update: function(){
var t = this;
t.phaze += 1;
//t.radius += cos(deg * t.phaze) * 0.5;
t.scale[0] = t.scale[1] = t.scale[2] = t.radius;
t.rot[2] += deg;
t.render();
}
};
var forceApplicator = {
update: function(){
var forceNum = forceList.length,
forceIndex,
force,
particleNum = particleList.length,
particleIndex,
particle,
posDiff,
distance,
distanceRadiusDiff,
m = n.Maths;
for(forceIndex = 0; forceIndex < forceNum; forceIndex += 1){
force = forceList[forceIndex];
for(particleIndex = 0; particleIndex < particleNum; particleIndex += 1){
particle = particleList[particleIndex];
posDiff = [
force.pos[0] - particle.pos[0],
force.pos[1] - particle.pos[1],
force.pos[2] - particle.pos[2]
];
distance = Math.sqrt(
m.square(posDiff[0]) +
m.square(posDiff[1]) +
m.square(posDiff[2])
);
distanceRadiusDiff = 1 - (distance / force.radius);
if(particle.index === 0){
//log(distance, distanceRadiusDiff);
}
if(distanceRadiusDiff > 0){
particle.vel[0] += force.charge * posDiff[0] * distanceRadiusDiff * 0.005;
particle.vel[1] += force.charge * posDiff[1] * distanceRadiusDiff * 0.005;
particle.vel[2] += force.charge * posDiff[2] * distanceRadiusDiff * 0.005;
}
}
}
}
};
scene.add(forceApplicator);
var myParticle, i, vx, vy, vz, phi, cosTheta, theta, radius;
for(i = 0; i < 160; i += 1){
//maths from here: http://stackoverflow.com/questions/5408276/python-uniform-spherical-distribution
phi = Math.random() * tau;
cosTheta = (Math.random() * 2) -1;
theta = Math.acos(cosTheta);
radius = Math.sqrt(Math.random());
vx = radius * sin(theta) * cos(phi);
vy = radius * sin(theta) * sin(phi);
vz = radius * cos(theta);
myParticle = new Particle({
vel: [
//1, 0, 0
vx,
vy,
0//vz
]
});
scene.add(myParticle);
}
var forceNum = 12,
forceFrac = tau / forceNum,
forceDistance = 150,
forceAngle,
force, x, y;
for(i = 0; i < forceNum; i += 1){
forceAngle = forceFrac * i;
x = cos(forceAngle) * (forceDistance * (i / forceNum) + 50);
y = sin(forceAngle) * (forceDistance * (i / forceNum) + 50);
force = new Force({
radius: 10 * i + 50,
pos: [
x,
y,
0
]
});
scene.add(force);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment