When I apply a series of AffineTransforms to an Area, it produces the wrong shape - translated by 0.9999 or so along x or y (which it then rounds to being out-by-1 if I call getBounds() to check it’s dimensions).
It depends where the shape starts in 2D co-ords! I can take a shape, translate it around a bit in increments of 10.f, and in most places tha AT’s + Areas come out exactly as they should - at multiples of 10.0f. At some offsets (so far, anything close to x = 0.0 or y = 0.0), they come out offset by an additional 0.9999.
It could be a problem with javax.vecmath, although I’d have thought it more likely to be J2D, because it’s somethign you’d never notice when painting pixels
…but you do when you have a zoom mode!
This is really distressing, because if it’s a bug in J2D/J3D/vecmath then, well, I’ve only got a few hours/days to find a workaround (sun game deadline almost upon us!). So, I’m hoping there’s something I’m doing that is an “obvious” source of loss-of-precision…?
FYI Tuple2f, Point2f and Vector2f are from javax.vecmath; everything else is java.awt.geom. The vecmath.jar I’m using is the one from Xith3d.org - but I don’t know where they got it.
First we have the code to create the Area from rectangular shapes (no rotations anywhere).
Tuple2f size = getSize();
Tuple2f sizeHalved = new Point2f( size );
sizeHalved.scale( 0.5f );
return new Area( new Rectangle2D.Float( -sizeHalved.x, -sizeHalved.y, size.x, size.y ) );
And then the code that composites mulitple rectangles:
for( Iterator it=allObjects.iterator(); it.hasNext(); )
{
GameObject object = (GameObject) it.next();
Area a = object.area(); // just the code above
Tuple2f position = object.getPosition();
AffineTransform toRoomSpace = AffineTransform.getTranslateInstance( position.x, position.y );
a.transform( toRoomSpace );
a.transform( roomSpaceToLevelSpace ); // just the code below
roomArea.add( a );
}
…and here is the pre-calculated roomSpaceToLevelSpace transform:
float cellsize = 10.0f;
levelOffset = new Vector2f( 10.0f, 10.0f );
AffineTransform roomSpaceToLevelSpace = AffineTransform.getScaleInstance( 1.0f / cellsize, 1.0f / cellsize );
roomSpaceToLevelSpace.preConcatenate( AffineTransform.getTranslateInstance( levelOffset.x, levelOffset.y ) );