switchboard/main.js

232 lines
5.6 KiB
JavaScript
Raw Normal View History

2013-02-25 11:48:30 +00:00
var Verlet = function(Width, Height)
{
this.Masses = [];
this.Constraints = [];
this.Width = Width;
this.Height = Height;
this.AddMass = function(Mass)
{
this.Masses.push(Mass);
2013-02-25 12:17:55 +00:00
return Mass;
}
this.AddConstraint = function(Constraint)
{
this.Constraints.push(Constraint);
2013-02-25 11:48:30 +00:00
}
this.Update = function(TimeDelta)
{
2013-02-25 12:17:55 +00:00
for (k in this.Constraints)
{
var c = this.Constraints[k];
if (typeof(c) == "function")
continue;
c.Update(TimeDelta);
}
2013-02-25 11:48:30 +00:00
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;
2013-02-25 12:17:55 +00:00
// shitty air friction
if (VY > 0)
VY = VY - TimeDelta
else
VY = VY + TimeDelta
if (VX > 0)
VX = VX - TimeDelta
else
VX = VX + TimeDelta
2013-02-25 11:48:30 +00:00
// 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;
}
}
}
2013-02-25 12:17:55 +00:00
var Constraint = function(Mass1, Mass2)
{
this.Mass1 = Mass1;
this.Mass2 = Mass2;
this.Distance = Math.sqrt(Math.pow(Mass1.X - Mass2.X, 2) + Math.pow(Mass1.Y - Mass2.Y, 2));
this.Update = function(TimeDelta)
{
var d1 = Math.sqrt(Math.pow(this.Mass1.X - this.Mass2.X, 2) + Math.pow(this.Mass1.Y - this.Mass2.Y, 2));
var d2 = (d1 - this.Distance) / d1;
var coefm1;
var coefm2;
if (!this.Mass1.Active)
{
coefm1 = 0;
coefm2 = 1;
}
else if (!this.Mass2.Active)
{
coefm1 = 1;
coefm2 = 0;
}
else
{
coefm1 = (this.Mass1.Weight / (this.Mass1.Weight + this.Mass2.Weight));
coefm2 = (this.Mass2.Weight / (this.Mass1.Weight + this.Mass2.Weight));
}
this.Mass1.X = this.Mass1.X - (this.Mass1.X - this.Mass2.X) * d2 * coefm1;
this.Mass2.X = this.Mass2.X + (this.Mass1.X - this.Mass2.X) * d2 * coefm2;
this.Mass1.Y = this.Mass1.Y - (this.Mass1.Y - this.Mass2.Y) * d2 * coefm1;
this.Mass2.Y = this.Mass2.Y + (this.Mass1.Y - this.Mass2.Y) * d2 * coefm2;
}
}
2013-02-25 11:48:30 +00:00
var v = new Verlet(800, 600);
2013-02-25 12:17:55 +00:00
var m1 = v.AddMass(new Mass(5, 5, 1));
var m2 = v.AddMass(new Mass(55, 100, 1));
var m3 = v.AddMass(new Mass(105, 5, 1));
v.AddConstraint(new Constraint(m1, m2));
v.AddConstraint(new Constraint(m2, m3));
v.AddConstraint(new Constraint(m1, m3));
2013-02-25 11:48:30 +00:00
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();
}
2013-02-25 12:17:55 +00:00
ctx.strokeStyle = '#FFFFFF';
for (k in v.Constraints)
{
var c = v.Constraints[k];
if (typeof(c) == "function")
continue;
ctx.beginPath();
ctx.moveTo(c.Mass1.X, c.Mass1.Y);
ctx.lineTo(c.Mass2.X, c.Mass2.Y);
ctx.stroke();
}
2013-02-25 11:48:30 +00:00
}, 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);