# CJ 2D Joint no rotation

This final version of the 2D joint removes the planar rotation so that no rotations are allowed. All that is allowed is translation along the two axes of the plane. It uses NewtonUserJointAddAngularRow to remove this last rotation.

## Construction

The construction code is the same as before. The plane vector can be anything you want and does not have to be normalised.

```Joint2D::Joint2D(NewtonBody* kpBody0, dVector kPlaneNormal)
{
mpBody0=kpBody0;
mPlaneNormal=kPlaneNormal;

dMatrix matrix0;
NewtonBodyGetMatrix(mpBody0, &matrix0);
mPlaneOrigin=matrix0.m_posit;

mpJoint=NewtonConstraintCreateUserJoint(mspWorld, 6, SubmitConstraints, mpBody0, 0);
NewtonJointSetUserData (mpJoint, (void*) this);
}
```

## SubmitConstraints

The constraint code begins the same but we add another an angular constraint. The error angle is extracted from the object transformation matrix.

Example C++ code:

```void Joint2D::LocalSubmitConstraints(const NewtonJoint* kpJoint)
{
dMatrix matrix0;
NewtonBodyGetMatrix(mpBody0, &matrix0);

// this line clamps the origin to the plane

// we can prevent rotation that takes any points out of the plane by clamping a point on the
// object that is on the line through the origin of the object with the same vector as the
// plane normal.  The clamp is to another plane that is parallel to the first, offset by the
// plane normal vector.  Rotations around either of the axes orthogonal to the plane normal
// will be prevented because they take the object point off that parallel plane.

dVector object_point;
dVector world_point;

object_point=matrix0.TransformVector(mPlaneNormal);
world_point=mPlaneOrigin+mPlaneNormal;

// that just leaves rotations around the plane's normal
// we can do this by equating matrix0 with a rotation matrix generated by an angle around the
// plane normal.  The equations can be solved for the angle which can then be fed into
// For an example of this matrix, see http://en.wikipedia.org/wiki/Rotation_matrix and look
// at the M(v,theta) matrix

dFloat temp;

// solving for the [0,0] matrix element gives the angle via arccos
dFloat x2=mPlaneNormal*mPlaneNormal;
temp=(matrix0.m_front-x2)/(1.0-x2);
// correct any numerical error
if (temp<-1.0)
temp=-1.0;
if (temp>1.0)
temp=1.0;
// end correct any numerical error
dFloat ac=acos(temp);

// we don't know the sign so we have to solve the [0,1] element as well
temp=(matrix0.m_front-(1.0-cos(ac))*mPlaneNormal*mPlaneNormal)/mPlaneNormal;
// correct any numerical error
if (temp<-1.0)
temp=-1.0;
if (temp>1.0)
temp=1.0;
// end correct any numerical error
dFloat as=asin(temp);

if (as>0.0)
ac*=-1.0;
dFloat angle=ac;