Is there a way to track/retrieve "global" position?

I have something like this,

push(); // Start head placement.
    translate( headPosition[0], headPosition[1] );
    rotate(headRotation);
    translate( -headPosition[0], -headPosition[1] );

    push(); // Start Eye1 placement.
      translate( eye1Position[0], eye1Position[1] );
      image(imgEye, 0, 0);
    pop(); // End Eye1 placement.

    push(); // Start Eye2 placement.
      translate( eye2Position[0], eye2Position[1] );
      image(imgEye, 0, 0);
    pop(); // End Eye2 placement.

    image(imgHead, 0, 0);
pop(); // End head placement.

So basically using a chain of push/pop matrix to place layers in relation to each other. Is there an easy way to find my global position?

If you did something like this,

push()
  translate(100, 100);
  a = retrieveGlobalPosition();
  push()
    translate(150, -66);
    push();
      translate(-27, 50);
      b = retrieveGlobalPosition();
    pop();
    c = retrieveGlobalPosition();
  pop();
pop();

then a should be [100, 100]. b should be [223, 84] and c should be [250, 34]. Or something along those lines. Hopefully that makes sense. So I want to be able to easily tell where an eye is located on the canvas and make calculations based on this position.

Is this possible? Or is there a better way to achieve this? Maybe using p5.Vector ?

This is fairly simple arithmetic when all you're doing is translating, and you could probably just keep track of your transforms via a variable. But once you start using rotate() as I did in my first example its going to get very complicated.

Eventually I think it would make sense to start parenting these objects to each other but my programming skills are not there yet.

Answers

  • This is possible, but computationally heavy, dark magic, and generally frowned on. Use screenX() and screenY().

  • Thanks for the reply!

    I've never used ThreeJS in the real world but it seems to support this kind of idea quite well. See here, http://stackoverflow.com/questions/21557341/three-js-get-world-rotation-from-matrixworld

  • Just don't use push/pop matrix: instead do the rotation yourself via a helper function so you're storing the actual location in your position arrays. The maths is actually relatively straightforward and you're doing the calculation that would otherwise happen in push/pop matrix so you shouldn't take a performance hit...

  • Thanks for your reply blindfish, sounds useful, but I admit I'm still relatively new to coding, so while I get the gist of what you're saying by adding a helper function, could you explain a bit further using pseudocode? Thanks, Marcus.

  • This isn't pseudocode; it's actual code; but written for Processing:

      PVector rotatePoint(float x, float y, float rotation) {
        PVector rotatedPoint = new PVector();
        float angle  = radians(rotation);
        rotatedPoint.x = cos(angle) * x - sin(angle) * y;
        rotatedPoint.y = cos(angle) * y + sin(angle) * x;
        return rotatedPoint;
      }
    

    I wrote this some time ago so won't claim it is optimal; but it demonstrates the concept.

  • edited October 2015

    AFAIK, p5.js already got a rotate() method for p5.Vector class:
    http://p5js.org/reference/#/p5.Vector/rotate

    Although I dunno whether it's equivalent to @blindfish's rotatePoint(). Check that out here:
    https://GitHub.com/processing/p5.js/blob/master/src/math/p5.Vector.js#L609

    Nonetheless I've rewritten rotatePoint() as rotateVector() for p5.js: :ar!

    function rotateVector(vec, rad) {
      const cosθ = cos(rad), sinθ = sin(rad);
      const x = cosθ * vec.x - sinθ * vec.y;
      const y = cosθ * vec.y + sinθ * vec.x;
      return vec.set(x, y, vec.z);
    }
    
Sign In or Register to comment.