2D rendering with positive y-axis going up (solved)

edited February 2017 in How To...

I want to write somefunction(float xmin, float xmax, float ymin, float ymax) which maps coordinates like:

 0,0 +--------+                              +---------+  xmax, ymax
     |        |                to            |         |
     |        |                              |         |
     +--------+ width,height       xmin,ymin +---------+

I could do this in processing 2 but changes in 3 invalidates previous method.

Answers

  • height-500

  • Do you want the bottom left corner of the display to be the origin [0,0] ?

  • Try this

    void setup() {
      size(600, 400);
    }
    
    void draw() {
      background(255);
      // ===================================================
      // Move origin to bottom left corner and invert Y axis
      translate(0, height);
      scale(1, -1);
      // ===================================================
      drawRect(50, 100, 120, 395);
    }
    void drawRect(float xmin, float xmax, float ymin, float ymax) {
      fill(255, 200, 200);
      stroke(128, 20, 20);
      rectMode(CORNERS);
      rect(xmin, ymin, xmax, ymax);
    }
    
  • @quark: I want to have an arbitrary position of bottom left corner, and I want it to work with everything, not just rect. image(), rect(), vertex(), qad(), line(), point(), etc.

    It's trivial to do in legacy opengl, and last time I did it by changing the matrix for PGraphicsOpenGL or similiar. I might have to dig around the source code again.

  • edited February 2017 Answer ✓

    I've solved it

    void simpleOrtho(float xLo, float xHi, float yLo, float yHi, float near, float far) {
      // need to use P2D renderer
      // calculations according to glOrtho spec
      float tx = -(xHi+xLo) / (xHi-xLo);
      float ty = -(yHi+yLo) / (yHi-yLo);
      float tz = -(far+near) / (far-near);
      float a = 2.0/(xHi-xLo);
      float b = 2.0/(yHi-yLo);
      float c = -2.0/(far-near);
      PMatrix3D mat = new PMatrix3D(); 
      mat.set(  a, 0.0, 0.0, tx, 
        0.0, b, 0.0, ty, 
        0.0, 0.0, c, tz, 
        0.0, 0.0, 0.0, 1.0);
      PGraphicsOpenGL gl = (PGraphicsOpenGL)g;
      gl.setProjection(mat);
    }
    

    I use it like this:

    final float w = 16;
    final float h = 9;
    
    float px = 0;
    float py = 0;
    
    void setup(){
      size(960,540,P2D);
    }
    
    void simpleOrtho(float xLo, float xHi, float yLo, float yHi, float near, float far) {
      // need to use P2D renderer
      // calculations according to glOrtho spec
      float tx = -(xHi+xLo) / (xHi-xLo);
      float ty = -(yHi+yLo) / (yHi-yLo);
      float tz = -(far+near) / (far-near);
      float a = 2.0/(xHi-xLo);
      float b = 2.0/(yHi-yLo);
      float c = -2.0/(far-near);
      PMatrix3D mat = new PMatrix3D(); 
      mat.set(  a, 0.0, 0.0, tx, 
        0.0, b, 0.0, ty, 
        0.0, 0.0, c, tz, 
        0.0, 0.0, 0.0, 1.0);
      PGraphicsOpenGL gl = (PGraphicsOpenGL)g;
      gl.setProjection(mat);
    }
    
    void keyPressed(){
      float speed = 0.3;
      if(keyCode == UP) py += speed;
      if(keyCode == DOWN) py -= speed;
      if(keyCode == LEFT) px -= speed;
      if(keyCode == RIGHT) px += speed;
    }
    
    void draw(){
      background(0);
      noStroke();
      fill(255);
    
      simpleOrtho(px,px+w,py,py+h,-100,100);
    
      for(int y = 0; y < 5; y++){
        for(int x = 0; x < 5; x++){
          if((x+y)%3==0)
            rect(x,y,1,1);
        }
      }
    
      fill(255,0,255);
      rect(w,h,-2,-2);
    
      fill(0,255,255);
      rect(w,h,2,2);
    }
    
Sign In or Register to comment.