Win a copy of Grokking Bitcoin this week in the Cloud/Virtualization forum!
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
• Campbell Ritchie
• Liutauras Vilda
• Bear Bibeault
• Tim Cooke
• Junilu Lacar
Sheriffs:
• Paul Clapham
• Devaka Cooray
• Knute Snortum
Saloon Keepers:
• Ron McLeod
• Tim Moores
• Stephan van Hulst
• Tim Holloway
• Frits Walraven
Bartenders:
• Carey Brown
• salvin francis
• Claude Moore

# AffineTransform Rectangle2D

Ranch Hand
Posts: 367
Hi!

I'm trying to rotate a Rectangle2D with some angles. I need draw a rectanglebox and in there a rotate rectangle from x,y to x + width , y+height. How can I do this. The rotate takes an angle and I don't know how to calculate the angle between my rectangles x,y and x + width , y + height

// Mathias

Ranch Hand
Posts: 1535

Mathias Nilsson
Ranch Hand
Posts: 367
Thanks but how do you know when to use Math.PI/4 , 6 and 3. is there somewhere I can calculate this during mousedrag?

Marshal
Posts: 64140
215
PI / 4 is 45� PI / 3 is 60� and PI / 6 is 30�.

Craig Wood
Ranch Hand
Posts: 1535
is there somewhere I can calculate this during mousedrag?
Probably, depends on what you are trying to do. If you wanted to click on a rectangle with
the mouse and drag so as to rotate the rectangle about a given point, eg, the center of
the rectangle, then you could calculate the initial angle of the line between the
mousePressed location and the rotation center, then calculate the angular change for each
mouseDragged event, pass this to the graphic component and add it to the last/current
rotation angle of the rectangle, compute an updated AffineTransform for the rotation and
call repaint to show the new rotation.

Greenhorn
Posts: 3
I have a similar problem. For a school project I'm writing a 2D Rigid Body Physics Engine in Java.

In order to simulate torque, I'm using AffineTransform.setToRotation(). Torque spins around the center-point, so I have

pos being a Point2D object, and .x and .y being the x and y coordinates of the rectangles center-point (found using getCenterX() and getCenterY().

This all works fine right up to the point where I assign a velocity vector to the rectangle, i.e. change pos.x and pos.x each time-step. As soon as I do this the rotation goes loopy, it doesn't rotate around the center-point anymore, but only close to the center-point.

I can't test whats going wrong because I use a Shape object to allow for AffineTransform.createTransformedShape();, and there are no getCenter() methods for Shape objects.

I tried using getRotateInstance to hopefully keep my rectangles as Rectangle2D objects and so be able to see whats happening with the center-point, but when I use getRotateInstance, rotation gets even loopier.

Here's my code, just to get a better idea of what I'm talking about. I have two rectangles, RectA and RectB, and hence two of each variable. To witness the loopiness, simply change any of the velocityA/B values to anything other than 0, positive or negative. 3 shows it pretty well.

Thanks in advance for your support. Should I post what I tried to do with getRotateInstance?

[ October 21, 2008: Message edited by: J.J. Zing ]
[ October 21, 2008: Message edited by: J.J. Zing ]

Author
Posts: 974
1

Originally posted by J.J. Zing:
Here's my code, just to get a better idea of what I'm talking about. I have two rectangles, RectA and RectB, and hence two of each variable. To witness the loopiness, simply change any of the velocityA/B values to anything other than 0, positive or negative. 3 shows it pretty well.

Hey there, JJ,

I think you need to do a little better job telling the details here. In particular:

(A) How exactly do I set one of the velocityA/B values to 3?
I tried changing velocityA = new Point2D.Double() to velocityA = new Point2D.Double(3,0) but I didn't see anything obviously loopy, which brings me to

(B) Can you describe how the actual behaviour differs from the expected
behaviour? I can see some rectangles flipping around. They look fine to
my untrained eye. How exactly are they flipping incorrectly? Presume I have no idea what your goals are. (Because I don't.)

Also, while I'm here, I feel I really need to point out that this isn't the proper way to do animation in Java. You have a loop in paint() that essentially never terminates. This results in bad things. For example have you noticed that you can't really quit your app?
What you should be doing is drawing one single frame in paint() that terminates quickly. Then elsewhere repeatedly call update() so that multiple calls to paint() will be scheduled.

J.J. Zing
Greenhorn
Posts: 3
Thanks for the quick response.
Sorry, I realise my info is a bit sparse and my post a bit cluttered.
If you change the values here:

the 'loopiness' should be visible. velocityA.y = 3; makes the rectangle move down 3 pixels each time-step, and you might be able to see that it doesn't rotate around its center anymore. When you changed velocityA = new Point2D.Double() to velocityA = new Point2D.Double(3,0) the change was undone later by velocityA.x = 0 etc.

The aim of this app is to realistically simulate physical interactions between rigid bodies. This means that when I'm done, the bodies will ideally be bouncing physically correctly off the walls and off each other. This 'physically correctly' is gonna be supplied by a few physics calculations, supplied to me by my friend doing physics and our school's physics text book. Each time a collision occurs, the velocity info is sent to the CollisionHandling (not yet written) class, which performs the necessary calculations to determine what changes need to be made to the velocities of the two bodies. For rectangles, this includes torque, or rotation around the center-point. Hence, its essential that the rectangles actually rotate around the center-point determined by me.

I realize I'm probably violating a whole slew of unwritten rules, and I would appreciate any guidance. This is the first time I'm writing Java outside of the classroom (I take Comp Sci in high-school) and there is a lot I have to learn.
The while (!done) loop will be made to end when a Collision is detected, and I was planning on making done = true; when the close button is clicked, which should solve the unquittable problem.

Would you care to elaborate on this paint() and update() method? I saw examples of it while browsing through tutorials, but never really looked into it / understood it. I understand the logic behind it, but am unsure as how to go about implementing it.

As the deadline is getting closer, I have decided to move from simulating rectangles to simply simulating circles, as my planned collision detection would only be able to tell me whether a collision had occured, but not where specifically (coordinates) this collision occurred, essential info if taking torque into account. Torque isn't important when simulating circles however, cause the spinning isn't visible. This gets rid of the loopiness problem (I'll see if I can't figure it out myself once I know more, and know better how to approach something like this). The assignment assess the 'journey of learning' rather than the end-product alone, so this shouldn't cost me any marks.

While I've gotten rid of one problem, I would still be grateful for any pointers as to animation etc. You also may have noticed that each time-step I g2.fillRect(0,0,this.getWidth(),this.getHeight()); to erase the previously drawn rectangles, and I realize this is also a horrible method, which the method mentioned by you seems to be able to fix.

Thanks again for your time and the quick response.
[ October 22, 2008: Message edited by: J.J. Zing ]

Craig Wood
Ranch Hand
Posts: 1535
Here's a comparison of the accuracy of two ways of animating a geom primitive.
Storing the location of the primitive in a Shape that is animating leads to
errors that compound. Another way is to keep the original primitive and draw it
as a transformedShape for animation.
To detect collision with this you can use the transformedShape with the Shape
intersects method. For circles you can use the Ellipse2D class and its
intersects method. For more complex shapes you can try the Area, Path2D
or Polygon classes.
Overriding the (Container) paint method in a JFrame is AWT drawing as
opposed to Swing drawing. Swing is double–buffered by default and makes
animations easier than they are in AWT drawing.
Using a separate JComponent extension, eg, JPanel, for drawing allows for Swing
drawing and for encapsulating graphics code in its own class.
There are different ways to do animation and everyone seems to have their
favorite/preferred idiom. Here's one way to approach it in Swing.

J.J. Zing
Greenhorn
Posts: 3