This problem is called Forward Kinematics. To solve this problem in general, I recommend creating what is called a Kinematic Chain, or Kinematic Tree. To do this, you will need knowledge of a 2D rotation matrix, or transformation matrix.
A 2D 3x3 transformation matrix is defined as:
H = [xx, xy, tx;
yx, yy, ty;
0, 0, 1];
In this case, [xx, yx] represents the x axis of the transformation, [xy, yy] represents the y axis, and [tx, ty] represents the translation of the transformation. For instance, the transformation:
H = [1, 0, 1;
0, 1, 0.5;
0, 0, 1];
translates a part 1 unit in the x direction, and 0.5 units in the y direction. To transform any vector, just pre-mulltiply it by the transformation matrix H. A special case of the transformation matrix is the rotation matrix. In 2D, a pure rotation can be represented as:
H = [cos(theta), -sin(theta), 0;
sin(theta), cos(theta), 0;
0, 0, 1];
where theta is the rotation value in Radians.
Now, to implement a Kinematic tree, you just need to do this:
// Represents a rigid link in a kinematic chain
// All links have exactly one or zero parent links.
// The "root" of the tree has no parent (NULL)
// All links can have as many children as needed
// Represents the transform from the parent link to
// this link.
// Reprsents the transform from the world to this link.
// Computes the global transform of this link with respect
// to the world. Then computes the global transforms of all
// If we're the root link, the global transform is the local transform.
if(!parent) globalTransform = localTransform;
// Otherwise, the global transform is the parent's global transform
// times our transform (matrix multiplication)
globalTransform = parent->globalTransform * localTransform;
// Now recursively compute the global transform for each of the children
for (Link* link : children)
To build the kinematic tree for your character, you just do this:
// The body is the base link, and starts at (0, 0) with 0 rotation.
Link* bodyLink = new Link();
bodyLink->parent = NULL;
bodyLink->localTransform = Matrix3x3::Identity();
// The left arm, relative to the body, is 50 pixels to the right and 10 up,
// with no local rotation.
Link* leftArm = new Link();
leftArm->parent = bodyLink;
leftArm->localTransform = Matrix3x3::CreateTranslation(50, 10);
// The right arm is 50 right and 10 down.
Link* rightArm= new Link();
rightArm->parent = bodyLink;
rightArm->localTransform = Matrix3x3::CreateTranslation(50, -10);
// The head is 10 right and 0 down
Link* head = new Link();
head->parent = bodyLink;
head->localTransform = Matrix3x3::CreateTranslation(10, 0);
You can rotate/translate the entire character just by moving around the body link:
bodyLink->localTransform.translation = Vector2(xPosition, yPosition);
bodyLink->localTransform.rotation = theta;
Then, to update, you just need to do this:
From there, you automatically get the global transforms (their rotations and translations):
Matrix3x3 headTransform = head->globalTransform;
Matrix3x3 leftArmTransform = leftArm->globalTransform;
Matrix3x3 rightArmTransform = rightArm->globalTransform;
You can also attach/detach nodes to different parts of the body to do things like make the character hold a gun, for instance.