Tracking Image Coordinates after Rotation

Hi, im trying to keep track of an images coordinates while its moved around the screen (using keyboard). Ive done this easily for UP, DOWN, LEFT and RIGHT movements but the problem is when the image is rotated at an angle (e.g. 45 degrees). How can i work out the coordinates of the image (top left corner) after it has been rotated?

this is what im using to rotate the image:

xform.rotate(Math.toRadians(angle), xRot , yRot);

xRot and yRot are ints that represent the centre of the image. This is the point im rotating about.

Any help is appreciated, thanks.

AffineTransform has this method:

transform(Point2D ptSrc, Point2D ptDst)

Transforms the specified ptSrc and stores the result in ptDst.

Does that do what you’re asking for?

Not sure if this method does what i want, not sure how to use it either… :-/ ill mess around with it anyway but i think the easiest way to explain the problem is with a picture, so here it is :slight_smile:


http://worldzone.net/gamers/shigsy/graphics/

so if i know the current x,y of the image, and i do a rotation on the image using
xform.rotate(Math.toRadians(angle), xRot , yRot);
then how do i calculate the new x,y? any ideas?

well assuming xform is an AffineTransform object, you just plop in a new Point2D.Double(x, y) into that method and it’ll return a new Point2D.Double() corresponding to the transformed x,y. So you’d use:


newPoint = xform.transform(new Point2D.Double(x,y), null);

newPoint.getX() is your new x, newPoint.getY()is your new y. Try it out

i did this

xform.rotate(Math.toRadians(angle), xRot , yRot);

newPoint = xform.transform(new Point2D.Double(soldier_x,soldier_y), null);

when i print newPoint (after rotating from 0,0) i get 19,-7 as the new x,y. These values look right considering the top left corner is now roughly 19 pixels to the right and -7 pixels up. So thanks alot.

i have another problem though. the man moves round the screen fine, but if i rotate him, the image appears at the origin and then rotates. Then if i try move the man again, he appears back in the position he was before the rotate, and then moves from that point. Any idea how i can make him rotate on the spot? Thanks again.

hi,

i’m rather new to java graphics but i think i struggled with the same problem as you do. i’m not sure if my solution is a good one but at least it worked for my racing game (http://www.cocktailz.org/nano.html). here’s what i did at the point where i had to draw a rotated instance of my race car:


// draw tha vehicle image
Graphics2D g2d = (Graphics2D) screenGraphics;

// save old xfrom to restore it later
AffineTransform origXform = g2d.getTransform();
AffineTransform newXform = (AffineTransform)(origXform.clone());
        
// calculate the center of rotation (DirectionVector is a helper class which represents a vector with dx, dy, angle and amount)
DirectionVector vehicleHeading = new DirectionVector(this.xFront - this.xRear, this.yFront - this.yRear);
double angle = vehicleHeading.getAngle();
        
int xRot = (int) (xCenter + this.vehicleWidth  / 2);
int yRot = (int) (yCenter + this.vehicleLength / 2);
        
// add transformations (last-added-first-applied)
newXform.translate((-1 * this.vehicleWidth / 2), (-1 * this.vehicleLength / 2));
newXform.rotate(Math.PI/2 + angle, xRot, yRot);
        
g2d.setTransform(newXform);
g2d.drawImage(this.vehicleImg, (int) xCenter, (int) yCenter, this.vehicleImgObserver);
g2d.setTransform(origXform);

i’m not sure if this is of any help for you but i remember that i had similar problems and the key hint was the
fact, that the xform transformations are applied in inverse order to how they are written in the code (see above).

hth, hanno

Thanks for the reply. Im not sure how to use this code though… does this code go in my paint method, and how do i use DirectionVector? Do i need to import something?
Thanks.

yes, this code should work in your paint method as long as you have a Graphics2D object to work with.
the DirectionVector is one of my self-written classes. all it does is representing a vector with a deltaX and deltaY component. anyway, this is not relevant for your problem. i just wanted to show the usage of the AffineTransform class.

Your code has helped alot, i didnt realise the transforms worked in reverse order as u have explained. But if i apply a transform to a Gaphics2D like u have done, then use that to draw the soldier, it rotate the entire screens contents.

Instead, i did it like this;

g2.drawRenderedImage(soldier, xform);

So thanks again for your help, seems to be working fine :slight_smile:

[quote]But if i apply a transform to a Gaphics2D like u have done, then use that to draw the soldier, it rotate the entire screens contents.
[/quote]
maybe you didn’t restore the original xForm obj like in the sample code above.

anyway, i’m glad that i could help you.
actually this is the first time where i could help someone else. usually i’m the one who needs help. :’(

now im having serious problems tracking the coordinates of the soldier! :frowning:

if i move up, down, left or right…then i simply add/subtract the soldiers speed (10 pixels) to/from the current x,y (which starts at 0,0). This works fine.

If i rotate at an angle or 45 degrees, then move up, this will cause the soldier to rotate clockwise 45 degrees and move forward 10 pixels. But the soldier isnt simply moving up 10 pixels as he normally would when i press the up key, instead he walks forward in the direction he is now facing (45 degrees). Obviously moving 10 pixels directly up will subtract 10 from the current y value and do nothing to the x value. Moving forward 10 pixels at an angle of 45 degrees is going to subtract from the current y and add to the current x. But how do i calculate how many pixels it has moved in both directions?

There has to be a way of getting the current x,y values of an image no matter where it is on the screen, and no matter what angle it is facing, without having to constantly track it yourself manually :frowning:

You could try AffineTransform.getTranslateX/Y()

Just used those methods as u suggested and they work perfect :slight_smile: Thanks alot.

I would suggest keeping track of everything in simple coordinates, not rotated. When you go to draw everything, set the transform of your Graphics2D context to the xform you’ve created. Then draw everything. That way everything EXISTS normally and simply, but everything RENDERS rotated.