From 89117810cbe14039c65ec2439d96b4b4e361cdda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergiusz=20Baza=C5=84ski?= Date: Mon, 25 Feb 2013 12:48:30 +0100 Subject: [PATCH] Basic verlet integrator. --- main.html | 9 ++++ main.js | 154 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 163 insertions(+) create mode 100644 main.html create mode 100644 main.js diff --git a/main.html b/main.html new file mode 100644 index 0000000..b444a59 --- /dev/null +++ b/main.html @@ -0,0 +1,9 @@ + + + Switchboard + + + + + + \ No newline at end of file diff --git a/main.js b/main.js new file mode 100644 index 0000000..2dde71f --- /dev/null +++ b/main.js @@ -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); \ No newline at end of file