views:

1093

answers:

3

Okay I'm trying to rotate a Java Polygon based on it's original position of angle 0. x, and y end up being converted to an int at the end of me using them, so I could understand not seeing some change, but when the difference in angles is big like 0 to 180 I think I should see something.

I've been at this for a little while and can't think of what it is. Here's the method. (Sorry if it messes up in the code tags, my firefox messes them up.)

public void rotate(double x, double y, obj o1)
{
    double dist = Math.sqrt(Math.pow(x - (o1.x + (o1.w/2)), 2) + Math.pow(y - (o1.y + (o1.h/2)),2));

    x +=  (Math.sin(Math.toRadians(o1.a)) * dist);
    y -=  (Math.cos(Math.toRadians(o1.a)) * dist); 
}
+4  A: 

FYI: Rotating shapes and points has been implemented in java.awt.geom.AffineTransform

Pierre
To be honest, I don't understand how to use AffineTransform. It's years a head of me in math. I'm still trying to grasp basic trig.
William
@William, affine transforms aren't particularly complex. Someone with basic algebra and trig should be able to study and implement them.
Simucal
@William, also, that class does it for you. So, if all you need is for it to work then viola, you have your rotation. If you want to understand affine transforms there are great articles on the net.
Simucal
+1  A: 

You're performing a 2D rotational transformation.

It ought to look something like this:

xnew = xold*cos(t) - yold*sin(t)
ynew = xold*sin(t) + yold*cos(t)

The rotation angle t must be in radians, of course. It's zero at the x-axis, and increased in the anti-clockwise direction.

Both the old and new points need to be expressed relative to the origin you're rotating about.

duffymo
+9  A: 

The values of x and y that are being manipulated in the rotate method will not be seen in the method that is calling it because Java passes method arguments by value.

Therefore, the x and y values that are being changed in the rotate method is a local copy, so once it goes out of scope (i.e. returning from the rotate method to its calling method), the values of x and y will disappear.

So currently, what is happening is:

x = 10;
y = 10;
o1 = new obj();
o1.a = 100;
rotate(x, y, obj);
System.out.println(x);  // Still prints 10
System.out.println(y);  // Still prints 10

The only way to get multiple values back from a method in Java is to pass an object, and manipulate the object that is passed in. (Actually, a copy of the reference to the object is passed in when an method call is made.)

For example, redefining rotate to return a Point:

public Point rotate(int x, int y, double angle)
{
    // Do rotation.
    return new Point(newX, newY);
}

public void callingMethod()
{
    int x = 10;
    int y = 10;
    p = rotate(x, y, 45);
    System.out.println(x);  // Should print something other than 10.
    System.out.println(y);  // Should print something other than 10.
}

That said, as Pierre suggests, using the AffineTransform would be much easier in my opinion.

For example, creating a Rectangle object and rotating it using AffineTransform can be performed by the following:

Rectangle rect = new Rectangle(0, 0, 10, 10);

AffineTransform at = new AffineTransform();
at.rotate(Math.toRadians(45));

Shape rotatedRect = at.createTransformedShape(rect);

AffineTransform can be applied to classes which implement the Shape interface. A list of classes implementing Shape can be found in the linked Java API specifications for the Shape interface.

For more information on how to use AffineTransform and Java 2D:

coobird
This is a really great answer. One problem I'm having though is that AT returns a shape and not a Polygon. I tried casting it, but that gave me a error when I ran the program.
William
Nevermind. Thanks for all your help. :)
William