Set Sprite Origin Without It Moving in LibGDX

In LibGDX when you change the origin of a sprite (via setOrigin), it will actually make the sprite jump to a different location if it has been scaled!

This is because when you change the origin, the scaling is reapplied at the new origin, making it appear to move. To counter this, we calculate just how much the re-scaling moves the sprite, and counter it.

The distance between the position at scale 1, and at scale S is, intuitively:

width – (scale * sprite_width)) * ((sprite_width – origin) / sprite_width)

That is, The width of the sprite, minus the scaled width, multiplied by position of the origin as a fraction of the width.

Take the difference between this value at the old origin and the new origin, and you have your correction distance!

Via algebra magic, we can simplify this greatly down, (and even cancel out the sprite width). Here is some Java code to set the origin of a scaled sprite without it moving Simply call setOrigin with the sprite and the intended new origin position.

public void setOrigin(Sprite s, float x, float y)
    float mx = calcDist(s.getScaleX(), s.getOriginX(), x);
    float my = calcDist(s.getScaleY(), s.getOriginY(), y);
    s.translate(-mx, -my);
    s.setOrigin(x, y);

private float calcDist(float scale, float o, float no)
    return -o + no + scale*o - scale*no;

Leave a Reply

Your email address will not be published. Required fields are marked *