Understanding rotate before translate

I’m on page 168 of “Getting Started with P5.js” and having a difficulty wrapping my head around the rotate() before translate() vs translate() before rotate():

When rotate() is before translate(), why does "The shape now rotates around the upper-left corner of the canvas”?

It seems to me that the behavior should be the same regardless of whether rotate() comes first or not.

i think translate sets the origin of the rotation.

the upper-left corner is the origin of the canvas and without a translation transform the shape will rotate around that point. if you translate first to the centre of the shape that becomes the origin of the rotation instead. well that’s my understanding at least.

2 Likes

Let me suggest also reading the 2D Transformations tutorial. It is for Processing, but the translate / rotate model is exactly the same.

https://processing.org/tutorials/transform2d/

Check out the section on rotation. It deals with this aspect of order: changing the origin of rotation, then rotating

3 Likes

One thing I miss in the Processing APIs compared to eg. Java2D is a form of rotate() that also takes the centre point to rotate around. Basically the concatenation of translate, rotate, translate back.

   pushMatrix();
    translate...
    rotate....
    //draw
   popMatrix();

Because 4 lines and using the matrix stack is better than one?! :stuck_out_tongue_winking_eye:

This is a really useful method https://docs.oracle.com/javase/8/docs/api/java/awt/Graphics2D.html#rotate-double-double-double-

I thought a rotate-around form of rotate had been proposed in the past as an addition to the API – but I’m not able to find it when searching issues https://github.com/processing/processing/issues?utf8=✓&q=is%3Aissue+rotate

In general, core devs are quite conservative about adding signatures due in part to maintenance headaches, but to me this does seem useful – in particular, conceptually useful for learners. The main downside from a project maintenance perspective might be that in addition to the reference, the major tutorials and examples don’t discuss it, so ideally they would also be updated.

void draw() {
  rotate(millis(), 50, 50);
  line(0, 0, 60, 0);
  rect(20, 20, 5, 5);
}
void rotate(float theta, float x, float y) {
  translate(x, y);
  rotate(theta);
  translate(-x, -y);
}

RotateAround--screenshot

example documentation from open-jdk: https://github.com/openjdk-mirror/jdk7u-jdk/blob/master/src/share/classes/java/awt/Graphics2D.java#L1009

1 Like

just out of curiosity:

do you mean that

  translate(x, y);
  rotate(theta);
  translate(-x, -y);

would be much faster than the usage of pushMatrix and popMatrix?

Because I have a menger sponger with 1000s of cubes…

thanks

Chrisir

@Chrisir – if you test your sponge with pushMatrix or with translate, which is faster? I’m curious. (Also, I wonder if it is the same for Java2D, P2D, P3D).

Pardon me, I mean test atomic calls. Clearly if you only push and pop once, then use local relative variables, that is faster. But 2000 translates is faster than 1000 pushes and 1000 pops – I think? The point being that the each form is “faster” depending on how you are using it in the larger code construct.

Thanks.

Hard to test, there’s a lot going on

Of course. Be well, take care of yourself.

1 Like

I thought it would clash with an existing P3D rotate() method but it seems not. Always thought it should be more like rotateAt() or rotateAround(). I have a few extra methods like that in PraxisLIVE (such as 7 parameter image()) but haven’t quite got around to this one yet.

Interestingly, there is a 4 parameter version of rotate() in Processing already though -

/**
   * Rotate around an arbitrary vector, similar to glRotate(), except that it
   * takes radians (instead of degrees).
   */

public void rotate(float angle, float v0, float v1, float v2)
1 Like

Interesting – Where did you find that in the source? Is it unimplemented in JAVA2D? I tried it with a default sketch, and it did nothing.

It’s in the PGraphics source code, although only implemented in PGraphicsOpenGL. I forgot this is in the p5js section. :wink:

@Chrisir the reason translate should be faster than the matrix stack is it only involves maths vs creating storage for the matrix values.

1 Like

Thanks for sharing reference; this helps.

1 Like