Skip to content
Browse files

Added Damped Spring. Renamed v.length to v.len to avoid conflict.

  • Loading branch information...
1 parent 815b3e0 commit 787b629ae1098e0699da608fee30dd39d775620c @josephg committed Jan 14, 2012
Showing with 249 additions and 6 deletions.
  1. +2 −1 Makefile
  2. +98 −1 cp.js
  3. +2 −2 cp.min.js
  4. +2 −1 demo/Joints.js
  5. +47 −0 demo/demo.js
  6. +97 −0 lib/constraints/cpDampedSpring.js
  7. +1 −1 lib/cpVect.js
View
3 Makefile
@@ -23,7 +23,8 @@ constraints = \
cpPinJoint.js \
cpSlideJoint.js \
cpPivotJoint.js \
- cpGrooveJoint.js
+ cpGrooveJoint.js \
+ cpDampedSpring.js
demos = demo.js \
ball.js \
View
99 cp.js
@@ -273,7 +273,7 @@ var vdot2 = function(x1, y1, x2, y2)
};
/// Returns the length of v.
-var vlength = exports.v.length = function(v)
+var vlength = exports.v.len = function(v)
{
return Math.sqrt(vdot(v, v));
};
@@ -5371,4 +5371,101 @@ GrooveJoint.prototype.setGrooveB = function(value)
this.activateBodies();
};
+/* Copyright (c) 2007 Scott Lembcke
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+var defaultSpringForce = function(spring, dist){
+ return (spring.restLength - dist)*spring.stiffness;
+};
+
+var DampedSpring = exports.DampedSpring = function(a, b, anchr1, anchr2, restLength, stiffness, damping)
+{
+ Constraint.call(this, a, b);
+
+ this.anchr1 = anchr1;
+ this.anchr2 = anchr2;
+
+ this.restLength = restLength;
+ this.stiffness = stiffness;
+ this.damping = damping;
+ this.springForceFunc = defaultSpringForce;
+
+ this.target_vrn = this.v_coef = 0;
+
+ this.r1 = this.r2 = null;
+ this.nMass = 0;
+ this.n = null;
+};
+
+DampedSpring.prototype = Object.create(Constraint.prototype);
+
+DampedSpring.prototype.preStep = function(dt)
+{
+ var a = this.a;
+ var b = this.b;
+
+ this.r1 = vrotate(this.anchr1, a.rot);
+ this.r2 = vrotate(this.anchr2, b.rot);
+
+ var delta = vsub(vadd(b.p, this.r2), vadd(a.p, this.r1));
+ var dist = vlength(delta);
+ this.n = vmult(delta, 1/(dist ? dist : Infinity));
+
+ var k = k_scalar(a, b, this.r1, this.r2, this.n);
+ assertSoft(k !== 0, "Unsolvable this.");
+ this.nMass = 1/k;
+
+ this.target_vrn = 0;
+ this.v_coef = 1 - Math.exp(-this.damping*dt*k);
+
+ // apply this force
+ var f_spring = this.springForceFunc(this, dist);
+ apply_impulses(a, b, this.r1, this.r2, this.n.x * f_spring * dt, this.n.y * f_spring * dt);
+};
+
+DampedSpring.prototype.applyCachedImpulse = function(dt_coef){};
+
+DampedSpring.prototype.applyImpulse = function()
+{
+ var a = this.a;
+ var b = this.b;
+
+ var n = this.n;
+ var r1 = this.r1;
+ var r2 = this.r2;
+
+ // compute relative velocity
+ var vrn = normal_relative_velocity(a, b, r1, r2, n);
+
+ // compute velocity loss from drag
+ var v_damp = (this.target_vrn - vrn)*this.v_coef;
+ this.target_vrn = vrn + v_damp;
+
+ v_damp *= this.nMass;
+ apply_impulses(a, b, this.r1, this.r2, this.n.x * v_damp, this.n.y * v_damp);
+};
+
+DampedSpring.prototype.getImpulse = function()
+{
+ return 0;
+};
+
})();
View
4 cp.min.js
2 additions, 2 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
View
3 demo/Joints.js
@@ -169,7 +169,8 @@ var Joints = function() {
boxOffset = v(0, 120);
body1 = addBall(posA, boxOffset);
body2 = addBall(posB, boxOffset);
- //space.addConstraint(cpDampedSpringNew(body1, body2, v(15,0), v(-15,0), 20, 5, 0.3f));
+ body2.setAngle(Math.PI);
+ space.addConstraint(new cp.DampedSpring(body1, body2, v(15,0), v(15,0), 20, 5, 0.3));
// Damped Rotary Springs
boxOffset = v(160, 120);
View
47 demo/demo.js
@@ -291,6 +291,46 @@ var drawLine = function(ctx, point2canvas, a, b) {
ctx.stroke();
};
+var springPoints = [
+ v(0.00, 0.0),
+ v(0.20, 0.0),
+ v(0.25, 3.0),
+ v(0.30,-6.0),
+ v(0.35, 6.0),
+ v(0.40,-6.0),
+ v(0.45, 6.0),
+ v(0.50,-6.0),
+ v(0.55, 6.0),
+ v(0.60,-6.0),
+ v(0.65, 6.0),
+ v(0.70,-3.0),
+ v(0.75, 6.0),
+ v(0.80, 0.0),
+ v(1.00, 0.0)
+];
+
+var drawSpring = function(ctx, scale, point2canvas, a, b) {
+ a = point2canvas(a); b = point2canvas(b);
+
+ ctx.beginPath();
+ ctx.moveTo(a.x, a.y);
+
+ var delta = v.sub(b, a);
+ var len = v.len(delta);
+ var rot = v.mult(delta, 1/len);
+
+ for(var i = 1; i < springPoints.length; i++) {
+
+ var p = v.add(a, v.rotate(v(springPoints[i].x * len, springPoints[i].y * scale), rot));
+
+ //var p = v.add(a, v.rotate(springPoints[i], delta));
+
+ ctx.lineTo(p.x, p.y);
+ }
+
+ ctx.stroke();
+};
+
// **** Draw methods for Shapes
@@ -368,6 +408,13 @@ cp.GrooveJoint.prototype.draw = function(ctx, scale, point2canvas) {
drawCircle(ctx, scale, point2canvas, c, 3);
};
+cp.DampedSpring.prototype.draw = function(ctx, scale, point2canvas) {
+ var a = this.a.local2World(this.anchr1);
+ var b = this.b.local2World(this.anchr2);
+
+ ctx.strokeStyle = "grey";
+ drawSpring(ctx, scale, point2canvas, a, b);
+};
var randColor = function() {
View
97 lib/constraints/cpDampedSpring.js
@@ -0,0 +1,97 @@
+/* Copyright (c) 2007 Scott Lembcke
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+var defaultSpringForce = function(spring, dist){
+ return (spring.restLength - dist)*spring.stiffness;
+};
+
+var DampedSpring = exports.DampedSpring = function(a, b, anchr1, anchr2, restLength, stiffness, damping)
+{
+ Constraint.call(this, a, b);
+
+ this.anchr1 = anchr1;
+ this.anchr2 = anchr2;
+
+ this.restLength = restLength;
+ this.stiffness = stiffness;
+ this.damping = damping;
+ this.springForceFunc = defaultSpringForce;
+
+ this.target_vrn = this.v_coef = 0;
+
+ this.r1 = this.r2 = null;
+ this.nMass = 0;
+ this.n = null;
+};
+
+DampedSpring.prototype = Object.create(Constraint.prototype);
+
+DampedSpring.prototype.preStep = function(dt)
+{
+ var a = this.a;
+ var b = this.b;
+
+ this.r1 = vrotate(this.anchr1, a.rot);
+ this.r2 = vrotate(this.anchr2, b.rot);
+
+ var delta = vsub(vadd(b.p, this.r2), vadd(a.p, this.r1));
+ var dist = vlength(delta);
+ this.n = vmult(delta, 1/(dist ? dist : Infinity));
+
+ var k = k_scalar(a, b, this.r1, this.r2, this.n);
+ assertSoft(k !== 0, "Unsolvable this.");
+ this.nMass = 1/k;
+
+ this.target_vrn = 0;
+ this.v_coef = 1 - Math.exp(-this.damping*dt*k);
+
+ // apply this force
+ var f_spring = this.springForceFunc(this, dist);
+ apply_impulses(a, b, this.r1, this.r2, this.n.x * f_spring * dt, this.n.y * f_spring * dt);
+};
+
+DampedSpring.prototype.applyCachedImpulse = function(dt_coef){};
+
+DampedSpring.prototype.applyImpulse = function()
+{
+ var a = this.a;
+ var b = this.b;
+
+ var n = this.n;
+ var r1 = this.r1;
+ var r2 = this.r2;
+
+ // compute relative velocity
+ var vrn = normal_relative_velocity(a, b, r1, r2, n);
+
+ // compute velocity loss from drag
+ var v_damp = (this.target_vrn - vrn)*this.v_coef;
+ this.target_vrn = vrn + v_damp;
+
+ v_damp *= this.nMass;
+ apply_impulses(a, b, this.r1, this.r2, this.n.x * v_damp, this.n.y * v_damp);
+};
+
+DampedSpring.prototype.getImpulse = function()
+{
+ return 0;
+};
+
View
2 lib/cpVect.js
@@ -56,7 +56,7 @@ var vdot2 = function(x1, y1, x2, y2)
};
/// Returns the length of v.
-var vlength = exports.v.length = function(v)
+var vlength = exports.v.len = function(v)
{
return Math.sqrt(vdot(v, v));
};

0 comments on commit 787b629

Please sign in to comment.
Something went wrong with that request. Please try again.