The Perspective Calculation

Hi there

I’m trying to calculate the location of a 3D vertex in a 2D viewing window.
According to this page
it should be as simple as

x' = (x*near)/z
y' = (y*near)/z

but I cannot find some sort of stable ground in the P5.js WEBGL space when using the default settings

here is a code to demonstrate

/*
When called with no arguments, the defaults provided are equivalent to 
perspective(PI/3.0, width/height, cameraZ/10.0, cameraZ10.0) where cameraZ is ((height/2.0) / tan(PI60.0/360.0));
[fovy]    PI/3.0,
[aspect]  width/height,
[near]    cameraZ/10.0,
[far]     cameraZ*10.0
*/

var fov;
var cameraZ;
var near;
var far;

var xPos, yPos;
var depth = 500;

function setup() {
  createCanvas(windowWidth, windowHeight, WEBGL);
  fov = PI / 3;
  cameraZ = (height / 2.0) / tan(fov / 2.0);


  near = cameraZ / 10.0;
  far = cameraZ * 10.0;

  perspective(fov, float(width) / float(height), near, far);

}

function draw() {
  background(54, 88, 200);
  orbitControl();

  xPos = mouseX - (width / 2);
  yPos = mouseY - (height / 2);
 
  ///////////////3d scene
  stroke(0);
  noFill();
  box(width, height, depth);
  fill(200, 54, 88);
  noStroke();

  push();
  translate(xPos, yPos, 0);
  sphere(20);
  pop();

  push();
  translate(xPos, yPos, -depth / 2);
  sphere(20);
  pop();

  push();
  translate(xPos, yPos, -depth);
  sphere(20);
  pop();

  //near
  rectMode(CENTER);
  fill(255, 32);
  push();
  translate(0, 0, near);
  rect(0, 0, width, height);
  pop();

  ///////////////2D
  /*
   x' = (x*near)/z
   y' = (y*near)/z
  */

  fill(54, 200, 88, 128);
  var pX = (xPos * near) / cameraZ;
  var pY = (yPos * near) / cameraZ;

  push();
  translate(0, 0, 0);
  rect(pX, pY, 40, 40);
  pop();

  //camera
  push();
  translate(0, 0, cameraZ);
  box(50);
  pop()

}

My point is to “project” a point in 3D space onto the screen coordinates.
this will allow for some primitive 2d picking for me

ps: with the lack of picking, I resort to my own calculations as I successfully did here

cheers guys ^^

1 Like

If I need to know where a 3D point is on a 2D screen, I use screenX() and screenY().

2 Likes

here is what i see

holy smoke !!

I found out that the proper calculation was

   pX = (cameraZ / (cameraZ + zPos)) * xPos; 
   pY = (cameraZ / (cameraZ + zPos)) * yPos;

but I find it amazing that , once again, there was a function doing that laying in plain sight*

*update: it is not available in p5.js, so here you go, use my little formula :]

thanks a lot @TfGuy44

3 Likes