Basic verlet integrator.
commit
89117810cb
|
@ -0,0 +1,9 @@
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Switchboard</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<canvas id="main"/>
|
||||||
|
<script type="text/javascript" src="main.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,154 @@
|
||||||
|
var Verlet = function(Width, Height)
|
||||||
|
{
|
||||||
|
this.Masses = [];
|
||||||
|
this.Constraints = [];
|
||||||
|
|
||||||
|
this.Width = Width;
|
||||||
|
this.Height = Height;
|
||||||
|
|
||||||
|
this.AddMass = function(Mass)
|
||||||
|
{
|
||||||
|
this.Masses.push(Mass);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.Update = function(TimeDelta)
|
||||||
|
{
|
||||||
|
for (k in this.Masses)
|
||||||
|
{
|
||||||
|
var m = this.Masses[k];
|
||||||
|
if (typeof(m) == "function")
|
||||||
|
continue;
|
||||||
|
|
||||||
|
m.Update(TimeDelta, {X: this.Width, Y: this.Height});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var Mass = function(X, Y, Weight)
|
||||||
|
{
|
||||||
|
this.Weight = Weight;
|
||||||
|
this.PX = this.X = X;
|
||||||
|
this.PY = this.Y = Y;
|
||||||
|
this.Active = true;
|
||||||
|
this.Update = function(TimeDelta, Bounds)
|
||||||
|
{
|
||||||
|
if (!this.Active)
|
||||||
|
return;
|
||||||
|
// do a verlet step
|
||||||
|
var VX = this.X - this.PX;
|
||||||
|
var VY = this.Y - this.PY;
|
||||||
|
this.PX = this.X;
|
||||||
|
this.PY = this.Y;
|
||||||
|
|
||||||
|
// add gravity (mgt^2/2)
|
||||||
|
VY = VY + (this.Weight * (9.98 * (TimeDelta*TimeDelta)) / 2) * 100;
|
||||||
|
|
||||||
|
// add speed to X, Y
|
||||||
|
this.X = this.X + VX;
|
||||||
|
this.Y = this.Y + VY;
|
||||||
|
// console.log(this);
|
||||||
|
|
||||||
|
// limit to bounds
|
||||||
|
if (this.Y < 0)
|
||||||
|
{
|
||||||
|
this.Y = 0;
|
||||||
|
this.VY = 0;
|
||||||
|
}
|
||||||
|
if (this.X < 0)
|
||||||
|
{
|
||||||
|
this.X = 0;
|
||||||
|
this.VX = 0;
|
||||||
|
}
|
||||||
|
if (this.Y > Bounds.Y)
|
||||||
|
{
|
||||||
|
this.Y = Bounds.Y;
|
||||||
|
this.VY = 0;
|
||||||
|
}
|
||||||
|
if (this.X > Bounds.X)
|
||||||
|
{
|
||||||
|
this.X = Bounds.X;
|
||||||
|
this.VX = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var v = new Verlet(800, 600);
|
||||||
|
v.AddMass(new Mass(5, 5, 1));
|
||||||
|
v.AddMass(new Mass(20, 5, 1));
|
||||||
|
v.AddMass(new Mass(35, 5, 1));
|
||||||
|
|
||||||
|
var c = document.getElementById("main");
|
||||||
|
var ctx = c.getContext('2d');
|
||||||
|
c.width = 800;
|
||||||
|
c.height = 600;
|
||||||
|
|
||||||
|
setInterval(function()
|
||||||
|
{
|
||||||
|
ctx.fillStyle = '#000000';
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.rect(0, 0, 800, 600);
|
||||||
|
ctx.closePath();
|
||||||
|
ctx.fill();
|
||||||
|
|
||||||
|
v.Update(1/50);
|
||||||
|
|
||||||
|
ctx.fillStyle = '#FFFFFF';
|
||||||
|
for (k in v.Masses)
|
||||||
|
{
|
||||||
|
var m = v.Masses[k];
|
||||||
|
if (typeof(m) == "function")
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.arc(m.X, m.Y, 5, 0, Math.PI*2, true);
|
||||||
|
ctx.closePath();
|
||||||
|
ctx.fill();
|
||||||
|
}
|
||||||
|
}, 1000/50);
|
||||||
|
|
||||||
|
|
||||||
|
var DragID = -1;
|
||||||
|
var DragOffsetX = 0;
|
||||||
|
var DragOffsetY = 0;
|
||||||
|
var DragMoveListener = function(e)
|
||||||
|
{
|
||||||
|
var MouseX = e.layerX - c.offsetLeft;
|
||||||
|
var MouseY = e.layerY - c.offsetTop;
|
||||||
|
var m = v.Masses[DragID]
|
||||||
|
m.PX = m.X;
|
||||||
|
m.PY = m.Y;
|
||||||
|
m.X = MouseX + DragOffsetX;
|
||||||
|
m.Y = MouseY + DragOffsetY;
|
||||||
|
}
|
||||||
|
var DragEndListener = function(e)
|
||||||
|
{
|
||||||
|
v.Masses[DragID].Active = true;
|
||||||
|
DragID = -1;
|
||||||
|
c.removeEventListener("mouseup", DragEndListener);
|
||||||
|
c.removeEventListener("mousemove", DragMoveListener);
|
||||||
|
c.addEventListener("mousedown", DragStartListener);
|
||||||
|
}
|
||||||
|
var DragStartListener = function(e)
|
||||||
|
{
|
||||||
|
var MouseX = e.layerX - c.offsetLeft;
|
||||||
|
var MouseY = e.layerY - c.offsetTop;
|
||||||
|
for (k in v.Masses)
|
||||||
|
{
|
||||||
|
var m = v.Masses[k];
|
||||||
|
if (typeof(m) == "function")
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var DX = MouseX - m.X;
|
||||||
|
var DY = MouseY - m.Y;
|
||||||
|
if (Math.sqrt((DX*DX) + (DY*DY)) < 5)
|
||||||
|
{
|
||||||
|
DragID = k;
|
||||||
|
DragOffsetX = DX;
|
||||||
|
DragOffsetY = DY;
|
||||||
|
m.Active = false;
|
||||||
|
c.removeEventListener("mousedown", DragStartListener);
|
||||||
|
c.addEventListener("mousemove", DragMoveListener);
|
||||||
|
c.addEventListener("mouseup", DragEndListener);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c.addEventListener("mousedown", DragStartListener);
|
Loading…
Reference in New Issue