I am attempting to test for a collision with a Rectangle2D.Float and a Point2D.Float. I have a 2D world that contains a camera (which transforms the graphics2D canvas based off the camera’s AffineTransform). I then have a list of objects X that contain sub-objects Y. The canvas is transformed ontop of the camera’s transformation to X’s AffineTransformation, so the object is rendered in the correct location. I can successfully test for a collision with the mouse inside Object X, but I am having issues testing for the sub objects Y because the Y objects “think” they are at position (0,0) even though they have been located elsewhere because of their parent object X who was repositioned to say (200,200). So in other words, Object X and Y show up at position (200,200), but the collision happens at (0,0) and not at (200,200) like it is supposed to.
I believe it has to do with the right combination of calling AffineTransform.transform and AffineTransform.inverseTransform, but I cannot wrap my brain around the correct combintation.
This is a standard problem that arises when using concatenated transformations for interactive graphics.
Let’s say
Tis the affine transformation matrix that positions an objectX. Also letUbe the matrix positioning some subobjectYwith respect toX. Then each pointpinYis being transformed with the matrix expressionwhere
p'is the transformed point. The coordinate space wherep'lives is the same as mouse coordinates. When you receive a mouse click at pointc'(I’m using the prime'here to matchp'in the same coordinates), you have a choice. You can either transformc'“backward” using(T U)^(-1)to getcin the coordinate space of the subobject. Or you can manually calculatep'for all pointspso you can compare it withc'.In general you will want to do the latter. The Java will be something like:
Now you will quickly notice that since you are manually calculating these points, you might keep a data structure of the transformed points around so you can always compare with mouse coordinates. The same data structure can be used for painting the screen with no transformations at all: they have already been applied. This is a pretty standard technique for interactive graphics. When the whole drawing is being updated rapidly, it loses its appeal. But when the drawing is large and at most small pieces are being updated at a time, it can be a big win for performance. You give some memory and get back some speed.