# How to position a sprite in a 2D animation skeleton?

Given two joints that define a bone, I would like to know how to decide where, between those two joints, I should draw the sprite. This should be a fairly simple thing to solve, but there is one thing that I am not sure about.

After I've determined the rotation of the sprite (which is the absolute angle the joints form with the x-axis), I also need to determine the origin point from where I need to start drawing the transformed image.

So how should I position the sprite between the two joints? Should I make the center of the image be the midpoint between the two joints, or should I make one the of the joints be the origin? Do these things matter that much (could the wrong positioning make the sprite move oddly during the animation)?

-
Are you using the "render a node/scene graph while concatenating matrices" approach or something else? – Torious Jun 9 '12 at 20:56

My 2D animation skeleton looks like this:

The large hollow circles represent constraints that the nodes (filled circles) have to other nodes. For example, I make sure that the elbow stays within some given distance of the shoulder.

To actually draw a `sprite` between nodes `n1` and `n2`, this is the function call I use in Love2D:

``````love.graphics.draw(sprite.img -- image
, n1.pos.x -- x coordinate
, n1.pos.y -- y coordinate
, (math.pi/2)-v.dir(n1.pos, n2.pos) -- orientation (radians)
, (n2.pos - n1.pos):len() / len -- x scale
, 1 -- y scale
, sprite.orig.x -- x offset
, sprite.orig.y -- y offset
)
``````

Your framework likely has a similar function.

I use the two nodes' positions to figure out the rotation and scale that the sprite should have. The vector library I use implements these with simple trigonometric functions and Pythagoras' theorem, respectively.

-

It sounds like for each bone you are currently defining the texture to be rendered - you might as well allow for more flexibility and include a texture origin offset in your bone structure as well (relative to either of the joints you choose). That way you can be sure the rendered texture will be consistently placed.

-

It's quite simple, you calc

``````vec2 dir = vec2_end_joint - vec2_start_joint
angle = dir.Angle();
//set origin of sprite if required here.
sprite.draw(vec2_start_joint, angle, calculated_scale_if_required);
``````

calculated_scale_if_required - is sprite size and your dir.Magnitude ratio

Or you can use matrix multiplication, like glRotate glScale, to make direct kinematics calculations and use your bones hierarchy.

-