Win an Ipad
  Developer   Demos & Samples   Revolute joint

Revolute joint

Screenshot
Learn how to use revolute joint in Moscrif. Joints are features connecting two bodies in a certain way. Revolute joint acts like a hinge, a pin, or an axle. Revolute joint connects two bodies together. These bodies can rotate around their anchor point. Revolute joint also supports limits and motors. We created this sample to demonstrate three rotors in action that rotate in the middle of the screen and collide with other bodies. We also added a new body for the users to interact with.

The typical uses of revolute joint are:

  • wheels or rollers
  • chains
  • rotating doors,
  • catapults,
  • levers

How to create a revolute joint

Revolute joint (same as all the other joints in Moscrif) is represented by its own class RevoluteJoint. This class has no constructor, meaning that it has to be created by createRevoluteJoint function. This function creates revolute joint between two bodies that are set in first two parameters. The anchor point is set by following two parameters (firstly x then y coordinate). The coordinates of anchor point are ordinary screen coordinates (in pixels). In the fifth parameter, we could set additional joint options (motor or limits). The last parameter specifies if box2d detects collisions between the bodies connected in the joint or not.

Example: creating revolute joint

var joint = PhysicsScene.createRevoluteJoint(bodyA, bodyB,anchorX, anchorY, jointSet, true);

Anchor point

Anchor point defines the point around which bodies in joint rotate. Body rotation is influenced by its mass and gravity as well. 

Image: anchor point

 

Motor

By default, revolute joint rotates without any resistance to interactions with other physical objects. It means, that bodies rotate if any force or mouse joint is applied onto them, or when the bodies collide with other objects. However, sometimes it is required to rotate the body by itself, without any interactions with other objects e.g.: when we want to create wheel on a vehicle. In such case, motor is used to rotate the joint. When the motor is specified, it tries to rotate by required speed. I wrote "tries to rotate", because it behaves like a real motor, so it can use only limited maximum torque specified in joint’s additional parameter motorTorque in (N•m). This means, that if something prevents the body rotating its speed is not guaranteed. The motor speed is set in angular velocity  in radians per seconds.

Example: creating motor

// joint's options
var jointSet = {
    enableMotor : true,             // enable motor
   motorSpeed  : (- 1 * Math.PI / 2) * (800.0 / System.width), // final speed is linearly depends on radius (screen resolution)
    maxMotorTorque : 2100000000,    // maximum torque }

In our sample we use a motor which creates three rotors in the middle of the screen. Every rotor consists of two bodies. One of the bodies should stay without movement or rotation. We set its type to static, meaning that it does not move under the gravity or joint. We create the revolute joints and rotating body in _createRotor function.

Example: creating joint

function _createRotor(x, y)
{
    var obj = {};
    // get dimensions of the body
    var (width, height) = (this._pictureRectangle.width, this._pictureRectangle.height);     // static body, which do not moves
    obj.bodyA = this.addPolygonBody(this._pictureRectangle, #static, 0.0, 1.0, 1.0, width, height);
    // place the body
    obj.bodyA.setPosition(x, y);     // create second rotating body
    obj.bodyB = this.addCircleBody(this._pictureCircle, #dynamic, 100.0, 0.0, 0.0, this._pictureCircle.width / 2);
    // place the body
    obj.bodyB.setPosition(x, y - System.width / 7 + this._pictureCircle.width / 4);
    // joint's options
    var jointSet = {
        enableMotor : true,             // enable motor
        motorSpeed  : (- 1 * Math.PI / 2) * (800.0 / System.width), // final speed is linearly depends on radius (screen resolution)
        maxMotorTorque : 2100000000,    // maximum torque     }
    // create joint
    var joint = this.createRevoluteJoint(obj.bodyA, obj.bodyB, x, y, jointSet, true);     // return object contains information about the joint
    return obj;
}

Limits

Sometimes the joint is allowed to rotate only in certain specific range of angle. To limit the joint rotation, we can set lower and upper limits. The limits are ideal to use for simulating limbs. However, we do not use limits in this sample.

Additional sample feature

To make sample more interesting, there are also some additional features which are not directly related to revolute joint.

Body creating

When the user taps on the screen, new body is added. It is added randomly in rectangle or circular shape. It has less mass than the body used in revolute joint. When the body in revolute joint collides with other body of the same mass, its reaction to collision is significant jump away from collision place. 

Example: creating a body in pointerPressed function

function pointerPressed(x, y)
{
    // renerate random shape (1 is rectangle body, else is circular body)
    var shape = rand(2);     if (shape == 1) {
        // get dimensions of the body
        var (width, height) = (this._pictureRectangle.width, this._pictureRectangle.height);
        // create the body
        var body = this.addPolygonBody(this._pictureRectangle, #dynamic, 1.0 /*density*/, 1.0/*friction*/, 0.5/*bounce*/, width, height);
        // place the body
        body.setPosition(x, y);
    } else {
        // get dimensions of the body
        var radius = this._pictureCircle.width;
        // create the body
        var body = this.addPolygonBody(this._pictureCircle, #dynamic, 1.0 /*density*/, 1.0/*friction*/, 0.5/*bounce*/, radius, radius);
        // place the body
        body.setPosition(x, y);
    }
}

Drawing joints

In enterprise applications, joints are not visible. They are invisible components and the user does not know that something like joint even exists. For the purpose of sample applications, the lines are drawn up to joints. All bodies connected in joint are remembered in _rotors array. Then, in draw function, we can get coordinates of the bodies and draw lines between them.

Example: draw function, that draws lines instead of joints

function draw(canvas) {
    var x1, y1, x2, y2;
    // fill background with black color
    canvas.clear(0xff000000);     // draw joints
    for (var i = 0; i < 3; i++) {
        // get position of both bodies
        (x1, y1) = this._rotors[i].bodyA.getPosition();
        (x2, y2) = this._rotors[i].bodyB.getPosition();
        // draw line
        canvas.drawLine(x1.toInteger(), y1.toInteger(), x2.toInteger(), y2.toInteger(), this._jointPaint);
    }
    // draw informative text
    canvas.drawText("Tap to add new objects.", (System.width - this._textWidth) / 2, 8*System.height / 10, this._textPaint);
    // draw other elements
    super.draw(canvas);
}

Change gravity

Gravity is changed according to the device position. If the user tilst the device, the gravity changes and all bodies fall down to the other side. However, the gravity is changing only on X axis to value -1.8 or 1.8N. If we kept changing the value of gravity on all axes; it would infuence the revolute joint significantly  (it would not rotate smoothly).

Example: change gravity acording to device position

function _startSensor()
{
    // check if accelometer sensor is available
    if (!Sensor.isAvailable(#acceleration)) {
        System.messageBox("No accelometer detected!");
    } else {
        // create sensor
        var sensor = new Sensor(#acceleration, 40);
        // setup handler for receiving data
        sensor.onDataReceived = function(sender, timestamp, params) {
            var (x, y, z) = (params[0], params[1], params[2]);
            if (x > 0)
                this super.setGravity(0, -1.8);
            else if (x < 0)
                this super.setGravity(0, 1.8);
        };
        // start receiving data
        sensor.start();
    }
}

Summary

Revolute joint connects two bodies which can rotate around the anchor point. It is suitable for connections like wheels, rollers, chains, rotating doors etc. In Moscrif we create  revolute joint by using function createRevoluteJoint. Revolute joint can also use motor to rotate with body in certain required speed, or limits to limit body rotation to given range of angles between upper and lower angle. Only dynamic body types can rotate in revolute joint.

 Distance joint   Mouse joint 
Write a Comment (0)
Subject
Please complete this mandatory field.
HTML Tags Not Allowed!
Comment
Please complete this mandatory field.