Box2d v2.1.0 user manual translation-Chapter 08th joint (joints)

Source: Internet
Author: User

Many excerpted content
Translated by Aman JiangBox2d v2.0.1 User Manual

Chapter 2 Joint)

8.1 about

Joints are used to constrain an object to the world or to other objects. A typical example of a game is a puppet, a dash, and a pulley. Combining joints in different ways can create interesting movements.

Some joints provide limit, allowing you to control the motion range. Some joints also provide a motor that can drive the joint at a specified speed until you specify a greater force or torque to offset the motion.

Joint motors have many different purposes. You can use the joint to control the position, as long as you provide a joint speed proportional to the distance from the target. You can also simulate joint friction: Set the joint speed to zero and provide a small but effective maximum force or torque; then the motor will try to keep the joints intact, until the load becomes too large.

8.2 joint definition

Each joint type has its own definition, but is derived from b2jointdef. All joints are connected to two different objects, one of which may be static. The joint can also be connected to two static or kinematic objects, but this does not have any practical purpose, it will only waste time on the processor.

You can specify user data for any joint type. You can also provide a tag to prevent collision of objects connected with joints. In fact, this is the default action. You can also set the collideconnected Boolean value to allow collision of connected objects.

Many joint definitions require you to provide some geometric data. An anchor point is often needed for a joint, which is a point fixed in an object. Box2d requires that these points be specified in the local coordinate system, so that even if the changes to the current object violate the joint constraints (Joint constraint ), the joint can still be specified-this often happens when the game saves or loads progress. In addition, some joints define the relative angle between objects by default. In this way, the rotation can be properly constrained.

Initializing geometric data may be boring. Therefore, many joints provide initialization functions, eliminating most of the work. However, these initialization functions are generally only applied to the prototype and should be directly defined in the product code. This makes joint behavior more robust.

The rest of the joint definition data depends on the joint type. Next we will introduce them.

8.3 Joint Factory)

The joints are created and destroyed using the World Factory method. This introduces an old problem:

Note:

Do not use new or malloc to create a joint in a stack or heap. To create or destroy objects and joints, you must use the create or destroy function corresponding to the b2world class.

Here is an example of the revolute joint process from creation to destruction:

B2revolutejointdef jointdef;

Jointdef. body1 = mybody1;

Jointdef. body2 = mybody2;

Jointdef. anchorpoint = mybody1-> getcenterposition ();

B2revolutejoint * Joint = myworld-> createjoint (& jointdef );

... Do stuff...

Myworld-> destroyjoint (joint );

Joint = NULL;

A good habit: when an object is destroyed, the corresponding pointer is cleared. If you try to use this pointer again, the program will crash at a specific time.

The lifecycle of the joints is not simple. Pay special attention to the following warnings and sound the alarm.

Note:

When an object is destroyed, the joints attached to it are also destroyed.

The above attention is not always necessary. You can organize your own game engine to ensure that the joints attached to an object are destroyed before the object is destroyed. In this case, you do not need to implement the listener class to listen to events where an object is destroyed. For more details, see the section "implicit destruction.

8.4 use joints

In many simulations, after a joint is created, it will not be accessed until it is destroyed. However, the joints contain a lot of useful data, allowing you to create a variety of simulations.

First, you can get objects, anchor points, and user data on the joints.

B2body * getbody1 ();

B2body * getbody2 ();

B2vec2 getanchor1 ();

B2vec2 getanchor2 ();

Void * getuserdata ();

All joints have reaction and torque, which are applied to the body2 anchor. You can use the reaction to break the joint (break joints) or cause other game events. These functions may need to be computed, so they are not called unless necessary.

B2vec2 getreactionforce ();

Float32 getreactiontorque ();

8.5 distance joint (distance joint)

The distance joint is one of the simplest joints. It means that the distance between two objects must be fixed when there is a difference between two objects. When you specify a distance joint, the two objects must be in the proper position. Then, you specify two anchors in the world coordinates. The first anchor connects to object 1, and the second anchor connects to object 2. These two points imply the length of the distance constraint.

This is an example of distance joint definition. In this case, we allow collision of objects.

B2distancejointdef jointdef;

Jointdef. initialize (mybody1, mybody2, worldanchoronbody1, worldanchoronbody2 );

Jointdef. collideconnected = true;

The distance joint can also be soft, just like connecting with a rubber band. Let's take a look at the web example in testbed to see what kind of behavior it has.

To make the joints flexible, you can adjust two parameters: frequency and damping ratio ). Think of the frequency as the speed at which the harmonic oscillator (harmonic oscillator, such as guitar string) vibrates. The frequency is specified in hertz. In typical cases, the joint frequency is less than half the time step frequency. For example, if you execute 60 time steps per second, the distance from the joint is less than 30Hz. The reason for doing so can be referred to the nycept frequency theory.

The Damping rate has no unit, typically between 0 and 1, and can be larger. 1 is the critical value of Damping rate. When the Damping rate is 1, there is no vibration.

Jointdef. frequencyhz = 4.0f;

Jointdef. dampingratio = 0.5f;

8.6 Rotating Joint (revolute joint)

The rotating joint forces two objects to share an anchor, that is, an articulated point. The rotating joint has only one degree of freedom: the relative rotation of two objects. This is called the joint angle.

To specify a rotating joint, you must provide an anchor for two objects and coordinates of the world. The initialization function assumes that the object is already in its proper position.

In this example, two objects are connected by the rotating joint, and the hinge point is the center of the first object.

B2revolutejointdef jointdef;

Jointdef. initialize (mybody1, mybody2, mybody1-> getworldcenter ());

When body2 rotates counterclockwise, the joint angle is positive. Like the angle in all box2d, the rotation angle is also in radians. According to the rules, when initialize () is used to create a joint, the rotation joint angle is 0 regardless of the current angle of the two objects.

Sometimes you may need to control the joint angle. To this end, the rotating joint can simulate joint restrictions and motors at will.

Joint limit forces the joint angle to be within a certain range. Therefore, it will apply enough torque. 0 should be in the range; otherwise, the joint may be tilted a little during simulation.

The joint motor allows you to specify the joint's angular velocity (time derivative of the angle), and the speed can be positive or negative. A motor can generate infinite power, but this is usually unnecessary. Think about the classic question:

"What happens when an irresistible force is used on an unmovable object? "

I can tell you this is not interesting. So you should provide a maximum torque for the joint motor. The joint motor is maintained at the specified speed unless the required torque exceeds the maximum torque. When the maximum torque is exceeded, the joint slows down and even reversely moves.

You can also use a joint motor to simulate joint friction. Set the joint speed to 0 and the maximum torque to be small and effective. In this way, the motor will try to stop the joint from rotating unless there is a heavy load.

Here is a revision to the definition of the above rotating joint; this time, the joint has a limit and a motor which is used to simulate friction.

B2revolutejointdef jointdef;

Jointdef. initialize (body1, body2, mybody1-> getworldcenter ());

Jointdef. lowerangle =-0.5f * b2_pi; //-90 degrees

Jointdef. upperangle = 0.25f * b2_pi; // 45 degrees

Jointdef. enablelimit = true;

Jointdef. maxmotortorque = 10.0f;

Jointdef. motorspeed = 0.0f;

Jointdef. enablemotor = true;

You can access the corner, speed, and motor torque of the rotating joint.

Float32 getjointangle () const;

Float32 getjointspeed () const;

Float32 getmotortorque () const;

After performing step, you can also update the motor parameters.

Void setmotorspeed (float32 speed );

Void setmaxmotortorque (float32torque );

Joint motors have some interesting functions. You can update the joint speed in each time step to make it swing forward and backward like a sine wave, or specify a function you want.

... Game loop begin...

Myjoint-> setmotorspeed (cosf (0.5f * Time ));

... Game loop end...

You can also use a joint motor to track the desired joint angle. For example:

... Game loop begin...

Float32 angleerror = myjoint-> getjointangle ()-angletarget;

Float32 gain = 0.1f;

Myjoint-> setmotorspeed (-gain * angleerror );

... Game loop end...

Generally, your gain parameter cannot be too large, or the joint may become unstable.

8.7 moving joint (Prismatic Joint)

The Prismatic Joint allows two objects to move relative to the specified axis, which prevents relative rotation. Therefore, the moving joint has only one degree of freedom.

The definition of the moving joint is similar to that of the rotating joint, but the rotation angle is changed to the translation, and the torque is changed to the force. In this analogy, we can see a definition of a moving joint with joint limitations and motor friction:

B2prismaticjointdef jointdef;

B2vec2 worldaxis (1.0f, 0.0f );

Jointdef. initialize (mybody1, mybody2, mybody1-> getworldcenter (), worldaxis );

Jointdef. lowertranslation =-5.0f;

Jointdef. uppertranslation = 2.5f;

Jointdef. enablelimit = true;

Jointdef. motorforce = 1.0f;

Jointdef. motorspeed = 0.0f;

Jointdef. enablemotor = true;

The rotating joint implies an axis shot from the screen, while the moving joint explicitly requires an axis parallel to the screen. This axis is fixed above two objects and moves along them.

Just like rotating a joint, when initialize () is used to create a moving joint, it is moved to 0. So make sure that 0 is within your mobile limit.

The usage of moving joints is similar to that of rotating joints. This is the corresponding function:

Float32 getjointtranslation () const;

Float32 getjointspeed () const;

Float32 getmotorforce () const;

Void setmotorspeed (float32 speed );

Void setmotorforce (float32 force );

8.8 pulley joint (pulley joint)

The pulley joint is used to create an ideal pulley that connects two objects to the ground. In this way, when one object rises, the other will fall. The rope length of the pulley depends on the initial configuration.

Length1 + length1 = constant

You can also provide a coefficient (ratio) to simulate block and tackle, which will make the movement on one side of the pulley faster than on the other side. At the same time, the stress on one side is smaller than that on the other side. You can also use this to simulate a mechanical lever ).

Length1 + ratio * length1 = constant

For example, if the coefficient is 2, the change of length1 is twice that of leng22. In addition, the binding force of the rope connecting body1 will be half that of the rope connecting body2.

When one side of the pulley is completely expanded, the length of the rope on the other side is zero, which may cause problems. In this case, the constrained equation becomes singular (bad ). Therefore, the pulley joint limits the maximum length of each side. You may also want to control the maximum length for gaming reasons. The maximum length can improve stability and provide more control.

This is an example of pulley definition:

B2vec2 anchor1 = mybody1-> getworldcenter ();

B2vec2 anchor2 = mybody2-> getworldcenter ();

B2vec2 groundanchor1 (p1.x, p1.y + 10.0f );

B2vec2 groundanchor2 (p2.x, p2.y + 12.0f );

Float32 ratio = 1.0f;

B2pulleyjointdef jointdef;

Jointdef. initialize (mybody1, mybody2, groundanchor1, groundanchor2, anchor1, anchor2, ratio );

Jointdef. maxlength1 = 18366f;

Jointdef. maxlength1 = 20366f;

The pulley joint provides a function to obtain the current length.

Float32 getlength1 () const;

Float32 getlength1 () const;

8.9 gear joint (gear joint)

If you want to create a complex mechanical device, gear may be required. In principle, you can use complicated shapes to simulate the Gear Teeth in box2d, but this is not very efficient and it may be boring. In addition, you have to carefully arrange the gears to ensure smooth meshing of the teeth. Box2d provides a simpler method for creating gears: Gear Joints.

The gear joint requires two rotated joints or objects that move the Ground joint. You can combine these joint types as needed. In addition, box2d must use the ground as body1.

Similar to the pulley coefficient, you can specify a gear coefficient (ratio), and the gear coefficient can be negative. It is also worth noting that when one is a rotating joint (angular) and the other is a moving joint (PAN), the gear coefficient has a length unit or the reciprocal of the length unit.

Coordinate1 + ratio * coordinate2 = constant

This is an example of a gear joint:

B2gearjointdef jointdef;

Jointdef. body1 = mybody1;

Jointdef. body2 = mybody2;

Jointdef. joint1 = myrevolutejoint;

Jointdef. joint2 = myprismaticjoint;

Jointdef. ratio = 2.0f * b2_pi/mylength;

Note: The gear joint depends on two other joints. This is fragile: What happens when other joints are deleted?

Note:

The gear joint should always be removed before rotating or moving the joint. Otherwise, your code will crash because the joint pointer in the gear joint is invalid. In addition, the gear joint should be deleted before any related objects are deleted.

8.10 mouse joint (mouse joint)

In the testbed example, the mouse joint is used to manipulate an object through the mouse. It tries to drag an object to the current cursor position. There is no restriction on rotation.

 

The definition of the mouse joint requires a target point, maximum force, frequency, and damping ratio ). The starting point of the target point coincides with the anchor of the object. The strongest force is used to prevent intense responses when multiple Dynamic Objects interact. If you want to set the maximum intensity to a large value, it will be big. The frequency and Damping rate are used to create an elastic effect, similar to the distance joint.

Many users attempt to modify the mouse and joint for the playability of the game. Users often want the mouse and joint to respond instantly and precisely to a certain point. In this case, the mouse and joint performance is not good. You can consider using kinematic objects instead.

8.11 linear joint (line joint)

Linear joints are similar to moving joints (Prismatic Joint), but there is no rotation constraint. Linear joints can be used to simulate hanging wheels. For more details, see b2linejoint. h.

8.12 weld joint (weld joint)

The purpose of the weld joint is to make the two objects do not move relative. Let's take a look at the cantilever example in testbed to see how the weld joints behave.

The idea of defining a split object with welded joints is tempting. However, due to the iterative solution of box2d, joint welding is a little unstable. As a result, the objects connected with the Welded Joints may swing.

A better way to create a split object is to use a single object with a lot of fixture on it. When an object is split, you can delete one of the original objects and recreate a new object with that fixture. Refer to the breakable example in testbed.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.