var Constraint = require('./Constraint')
, AngleLockEquation = require('../equations/AngleLockEquation')
, Utils = require('../utils/Utils');
module.exports = GearConstraint;
/**
* Constrains the angle of two bodies to each other to be equal. If a gear ratio is not one, the angle of bodyA must be a multiple of the angle of bodyB.
* @class GearConstraint
* @constructor
* @author schteppe
* @param {Body} bodyA
* @param {Body} bodyB
* @param {Object} [options]
* @param {Number} [options.angle=0] Relative angle between the bodies. Will be set to the current angle between the bodies (the gear ratio is accounted for).
* @param {Number} [options.ratio=1] Gear ratio.
* @param {Number} [options.maxTorque] Maximum torque to apply.
* @extends Constraint
*
* @example
* var constraint = new GearConstraint(bodyA, bodyB);
* world.addConstraint(constraint);
*
* @example
* var constraint = new GearConstraint(bodyA, bodyB, {
* ratio: 2,
* maxTorque: 1000
* });
* world.addConstraint(constraint);
*/
function GearConstraint(bodyA, bodyB, options){
options = options || {};
Constraint.call(this, bodyA, bodyB, Constraint.GEAR, options);
/**
* The gear ratio.
* @property ratio
* @type {Number}
*/
this.ratio = options.ratio !== undefined ? options.ratio : 1;
/**
* The relative angle
* @property angle
* @type {Number}
*/
this.angle = options.angle !== undefined ? options.angle : bodyB.angle - this.ratio * bodyA.angle;
// Send same parameters to the equation
var angleLockOptions = Utils.shallowClone(options);
angleLockOptions.angle = this.angle;
angleLockOptions.ratio = this.ratio;
this.equations = [
new AngleLockEquation(bodyA,bodyB,angleLockOptions),
];
// Set max torque
if(options.maxTorque !== undefined){
this.setMaxTorque(options.maxTorque);
}
}
GearConstraint.prototype = new Constraint();
GearConstraint.prototype.constructor = GearConstraint;
GearConstraint.prototype.update = function(){
var eq = this.equations[0];
var ratio = this.ratio;
if(eq.ratio !== ratio){
eq.setRatio(ratio);
}
eq.angle = this.angle;
};
/**
* Set the max torque for the constraint.
* @method setMaxTorque
* @param {Number} torque
*/
GearConstraint.prototype.setMaxTorque = function(torque){
this.equations[0].setMaxTorque(torque);
};
/**
* Get the max torque for the constraint.
* @method getMaxTorque
* @return {Number}
*/
GearConstraint.prototype.getMaxTorque = function(){
return this.equations[0].maxForce;
};
example
<!DOCTYPE html>
<html>
<head>
<title>GearConstraint demo - p2.js physics engine</title>
<script src="../build/p2.js"></script>
<script src="../build/p2.renderer.js"></script>
<link href="css/demo.css" rel="stylesheet"/>
<meta name="description" content="Demonstrates the GearConstraint that syncs the rotation of two bodies with some gear ratio.">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
</head>
<body>
<script>
// Create demo application
var app = new p2.WebGLRenderer(function(){
var world = new p2.World({
gravity : [0,-10]
});
this.setWorld(world);
// Create first circle
bodyA = new p2.Body({
mass: 1,
position: [-2,0],
angle: Math.PI/2,
angularVelocity : -5,
});
bodyA.addShape(new p2.Circle({ radius: 1 }));
world.addBody(bodyA);
// Create second circle
bodyB = new p2.Body({
mass: 1,
position: [2,0],
});
bodyB.addShape(new p2.Circle({ radius: 1 }));
world.addBody(bodyB);
// Create a dummy body that we can hinge them to
var dummyBody = new p2.Body();
world.addBody(dummyBody);
// Hinge em
revoluteA = new p2.RevoluteConstraint(dummyBody, bodyA, {
worldPivot: bodyA.position
});
revoluteB = new p2.RevoluteConstraint(dummyBody, bodyB, {
worldPivot: bodyB.position
});
world.addConstraint(revoluteA);
world.addConstraint(revoluteB);
// Add gear
gearConstraint = new p2.GearConstraint(bodyA,bodyB,{ ratio: 2 });
world.addConstraint(gearConstraint);
});
</script>
</body>
</html>
Comments