# chained object rotation on a fix point

This topic is 4147 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I'm having trouble with rotation on a fixed point. There are a line of sphere that I have already created. and let say I have a point name with jointX,jointY which are the location that I want my lines of sphere to rotate from(not from the origin). but I got stuck at a point where the line of sphere disappear. some code might explain my problem

float tempX = 0;
float tempY = 0;
float updateX;
float updateY;

_jointX = upperLegJointX;     //the point of rotation
_jointY = upperLegJointY;

for(int i = 0; i < 10; i++){

objects sphere = lowerLegArray;		//get each sphere in the array

tempX = sphere.getLocationX();		//get the current X location of the sphere within the array
tempY = sphere.getLocationY();		//get the current Y location of the spehre within the array

//calclate the new X Y location of the sphere
updateX = cos((float)0.05f) * _jointX - sin((float)0.05f) * _jointY;
updateY = sin((float)0.05f) * _jointX + cos((float)0.05f) * _jointY;

//translate back into the origin using the original X/Y(tempX/Y)
//then tranlte it into the new calculated value
glPushMatrix();
glTranslatef(updateX, updateY , 0);
glTranslatef(tempX, tempY, 0);
sphere.sphere();
glPopMatrix();

lowerLegArray.setLocation(updateX, updateY);			//save it back into the array

}


it seems that every single sphere keep translate back to the joint's location. Any suggestion that might solve this problem? Is all I missing is the displacement between the joint and the new location of the sphere? [Edited by - jmcheng on October 15, 2006 11:12:52 PM]

##### Share on other sites
It looks like your geometry is off. In order to rotate a point about an arbitrary position, you should employ the conjugate transform: translate, rotate, inverse translate. Unless you're after an axis-aligned elliptical orbit, the sines and cosines in the rotation code should all be multiplied by the same factor. Also, you are saving only part of the transformation back to the object: The 'rotated' value gets stored whereas the final translation only makes it to the matrix stack, which is just as soon destroyed.

A couple of other more cosmetic points:

Variables should be declared as close to their use as possible.

There's no good reason (that I can see) to have an underscore on _jointX/_jointY. This won't cause any trouble as it is but will get you into bad habits. Variables names starting with an underscore followed by a capital letter are reserved for the compiler and should never be used by the programmer.

You're making a copy of each sphere inside the loop. There's no need for this and it is just slowing you down. You should use a reference.

Straight for loops are rather going out of fashion in favour of std::for_each. You don't really have to change this, but if you do make a habit of using for_each whenever appropriate, you'll avoid bugs and probably impress employers.

'objects' isn't the greatest class name I've ever seen.

Hard-coded array bounds are bad and will give you a headache sooner or later, when you need to change the bound. Use a const instead.

It is a little confusing to mix matrix transformations with manual transformations, particularly in this case when either would do just fine.

So assuming you're after circular orbits, I imagine the correct code would look something like:

const long NUM_SPHERES = 10;float angular_velocity = 0.05f / desired_fps; // For consistencyfloat jointX = upperLegJointX;     // Point of rotationfloat jointY = upperLegJointY;	for(int i = 0; i < NUM_SPHERES; ++i){    CSphere &sphere = lowerLegArray; // Use a reference or use the object itself                                         // rather than making unnecessary copies		    float x = sphere.getLocationX();    float y = sphere.getLocationY();    // Translate    x = x - _jointX;    y = y - _jointY;    // Rotate    float angle =  angular_velocity * elasped_time; // For frame independent motion,                                                      // instead of your hard-coded 0.05f    float updateX = cos(angle) * x - sin(angle) * y;    float updateY = sin(angle) * x + cos(angle) * y;    // Inverse translate    updateX = updateX + _jointX;    updateY = updateY + _jointY;    // Save the result    lowerLegArray.setLocation(updateX, updateY);    sphere.sphere(); // I'm not sure what this is supposed to do so I left it in}

I haven't defined all the variables I invented, but everything should be fairly self-explanatory.

Regards