views:

49

answers:

2

Hi. I'm trying to create a spinning airplane propeller in Java 3D. At the moment, it is rotating around the origin. However, I need it to rotate around itself. I haven't done much 3D graphics in Java, so I'm pretty much stumped.

TransformGroup rotateTheBlades = new TransformGroup();
rotateTheBlades.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
Alpha rotationAlpha = new Alpha(-1,5000);

RotationInterpolator rotator = new RotationInterpolator(
         rotationAlpha,rotateTheBlades);

Transform3D abc = new Transform3D();
abc.rotZ(Math.PI/2);

rotator.setTransformAxis(abc);
rotator.setSchedulingBounds(new BoundingSphere());
rotateTheBlades.addChild(rotator);
rotateTheBlades.addChild(propeller);

sceneBG.addChild(rotateTheBlades);

Any help would be greatly appreciated. PS: I tried to translate it to the origin before and after but it doesn't seem to do anything whatsoever.

+1  A: 

Without knowing enough Java to give a complete answer; the correct solution in maths terms is as you suspect: translate centre of the object to origin, rotate, then translate it back to its original position.

However, it's likely (ie, I'm guessing) that when you combine transformations, they're post-multiplied to give the effect that transformations happen in model space. What you probably want is pre-multiplication, to give the effect that transformations occur in world space.

Consider the sails of a windmill. In code you'd want to be able to translate to the top of the windmill, then call the routine that draws the sails. That routine might apply a rotation and then draw. But in terms of transformations, you actually you want to rotate the sails while at the origin so that they rotate around their centre, then move them out. So the transformations are applied in the opposite order to the order in which you request them.

What that means is, you want to apply the transformations as:

  1. move away from the origin
  2. rotate
  3. move to the origin

For example, if you were in OpenGL (which is also a post-multiplier, and easy enough to follow in this example even if you don't actually know it) you might do:

glTranslatef(centreOfBody.x, centreOfBody.y, 0.0f);
glRotatef(angle, 0.0f, 0.0f, 1.0f);
glTranslatef(-centreOfBody.x, -centreOfBody.y, 0.0f);
Tommy
A: 

The approach suggested by @Tommy is correct. Like GL, transformations of the Java graphics context are concatenated "in the most commonly useful way," which I think of as last-in, first-out. A typical paintComponent() method is shown below and in this complete example.

@Override
public void paintComponent(Graphics g) {
    super.paintComponent(g);
    Graphics2D g2d = (Graphics2D) g;
    g2d.translate(this.getWidth() / 2, this.getHeight() / 2);
    g2d.rotate(theta);
    g2d.translate(-image.getWidth(null) / 2, -image.getHeight(null) / 2);
    g2d.drawImage(image, 0, 0, null);
}
trashgod