smaili
smaili

Reputation: 1235

Getting Scene2D Actor's position after rotating in Libgdx

I have the following rotation function:

public void rotate( Actor a ) {
    float rotateBy = 30.0f,
          newX = ( a.getX() * ( float ) Math.cos( rotateBy ) ) - ( a.getY() * ( float ) Math.sin( rotateBy ) ),
          newY = ( a.getX() * ( float ) Math.sin( rotateBy ) ) + ( a.getY() * ( float ) Math.cos( rotateBy ) ),
          moveByX = a.getX() - newX, // delta
          moveByY = a.getY() - newY, // delta
          duration = 1.0f; // 1 second

    a.addAction(
        Actions.sequence(
            Actions.parallel(
                Actions.rotateBy( rotateBy, duration ),
                Actions.moveBy( moveByX, moveByY, duration )
            )
        )
    );
}

But it seems the moveByX and moveByY values are not accurate.

The goal is to figure out what the new x,y would be after rotation, and move up by that much so that it still maintains the same y as before it was rotated.

Desired result

Also, my Actor's draw method:

    @Override
    public void draw( Batch batch, float parentAlpha ) {
        batch.draw( texture, getX(), getY(), getWidth()/2, getHeight()/2, getWidth(), getHeight(), getScaleX(), getScaleY(), getRotation() );
    }

Upvotes: 1

Views: 1365

Answers (1)

zappp
zappp

Reputation: 110

This is the way I would do it: first the origin of the actor must be the center of the square, then rotate the actor on its center and you will see something like this

problem

The red line represent the y-offset that the actor needs to be moved up in order to follow the floor, as you can see this y-offset increases and decreases (so maybe you can't use Actions.moveBy because this move it along a linear way and your path isn't linear, see the blue line) so

Vector2 pos = new Vector2();
public void rotate(float delta, Actor a) {
    a.rotateBy(angularSpeed*delta);
    pos.x += linearSpeed*delta;
    a.setPosition(pos.x,pos.y+yOffset(a.getRotation());
}

yOffset is the function that describes the lenght of the red line based on the square rotation angle:

public float yOffset(float angle) {
    angle %= Math.PI/2;
    return (float) Math.abs(squareSize*(Math.sin((Math.PI/4+angle))-Math.sin(Math.PI/4)));
}

All angles are in radians.

Upvotes: 1

Related Questions