简体   繁体   中英

Transformations in Java2D API

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 T is the affine transformation matrix that positions an object X . Also let U be the matrix positioning some subobject Y with respect to X . Then each point p in Y is being transformed with the matrix expression

p' = T U p

where p' is the transformed point. The coordinate space where p' lives is the same as mouse coordinates. When you receive a mouse click at point c' (I'm using the prime ' here to match p' in the same coordinates), you have a choice. You can either transform c' "backward" using (TU)^(-1) to get c in the coordinate space of the subobject. Or you can manually calculate p' for all points p so you can compare it with c' .

In general you will want to do the latter. The Java will be something like:

AffineTransform TU = new AffineTransform(T);
TU.concatenate(U);
Point2D pPrime = new Point2D();
TU.transform(p, pPrime);

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.

As shown in this example , several things may help:

  • Distinguish between transforming the graphics context and transforming a Shape .

  • Transformations are not commutative; they are concatenated , as if applied in an apparent last-specified-first-applied order.

  • AffineTransform includes static factories that allow for an anchor point.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM