2
\$\begingroup\$

I am currently implementing a 2D skeleton system in C# with XNA, but got stuck in how I would rotate the bones around a skeleton's axis.

A basic algorithm that I have figured out already would involve, one part or another, manipulating the coordenates of the bone around the axis. I just cannot find the equation that would return these coordenates once provided an angle.

For example, if the bone's axis.X originally is -1 and its axis.Y -2 units away from the skeleton's axis' X and Y, then when the skeleton is rotated 90 degrees the X difference would become 2 and the Y, -1 (illustrated).

I'm certain the function I'm looking for would end something like this:

    void rotateVector (Vector2 vectorToAnalyze, Vector2 axis, float currentAngle, float newAngle, out Vector2 result);

If there are already functions that do the job, then I wouldn't mind using them - I'm certain there's something in the Matrix class related to this, but I'm a bit overwhelmed by it. As much it really would be nice to learn how this whole deal rolls, the most important thing to me, simply, is to find a solution that works this way I intend.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ This is a good time to learn a little matrix math (especially rotations on axes, using Sine and Cosine). The goal is to position the points relative to the centre of the rotation. If you've got a whole skeleton you're spinning, point at the abdomen for [0,0] and then propagate down the line (update bones based on transforms from their parent). If you want to spin a propeller, set the verts relative to the center of the prop. If you've got a forearm you're flexing, then position the verts relative to the elbow as 0,0. If I get to a PC before anybody answers, I might break that down more. \$\endgroup\$
    – LetterEh
    Commented Jan 9, 2013 at 3:30

2 Answers 2

1
\$\begingroup\$

You might be overcomplicating this a bit - plus this is something the different matrixes have been introduced for.

This is how I'd do this (don't calculate the rotation and stuff in software; it might be nice for a training exercise, but in the end let the graphics hardware do the math):

  • Set your bone's local coordinates (i.e. the vertex coordinates) in a way that its origin is in the center (i.e. the point where you'd like to rotate it). You only have to do this once.
  • Reset the bone's projection matrix to the identity matrix. Now the bone won't be rotated or translated at all.
  • Apply the rotation you're looking for (the correct angle).
  • Now apply the proper transformation (i.e. move the bone where you want it to be on screen).

Once this is done, the bone should be rotated and where you want it to be.

What you're experiencing here is doing this in the wrong order (translating the bone first, then rotating), which just overcomplicates things a lot.

\$\endgroup\$
0
\$\begingroup\$

Assuming that your bone has Parent bone, Length and Rotation (not transformed), then:

BeginPosition = Parent.EndPosition;
TransformedRotation = Rotation + Parent.TransformedRotation;
var v = new Vector2f(Length, 0);
v = v.Rotate(TransformedRotation);
EndPosition = bone.BeginPosition + v;

Rotate is my extension method:

public static Vector2 Rotate(this Vector2 v, float angle)
{
    var sin = (float)Math.Sin(angle);
    var cos = (float)Math.Cos(angle);
    return new Vector2(v.X * cos - v.Y * sin, v.X * sin + v.Y * cos);
}

Note that you have to update parent before it's children.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .