# The Perspective Calculation

**URL:** <https://discourse.processing.org/t/the-perspective-calculation/988>\
**Category:** p5.js\
**Created:** [June 15, 2018, 12:19pm UTC](https://discourse.processing.org/t/the-perspective-calculation/988 "2018-06-15T12:19:29Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![phoebus](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/phoebus/32/481_2.png) [@phoebus](https://discourse.processing.org/u/phoebus)\
**Post date:** [June 15, 2018, 12:19pm UTC](https://discourse.processing.org/t/the-perspective-calculation/988/1 "2018-06-15T12:19:30Z")

</div>

Hi there

I’m trying to calculate **the location of a 3D vertex in a 2D viewing window**.  
According to [this page](http://learnwebgl.brown37.net/08_projections/projections_perspective.html)  
it should be as simple as

```auto
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

 ![perspective_divide](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/1X/289d82083a269c951d6cdc6a787f7019885efe75.jpg)

here is a code to demonstrate

```auto
/*
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](https://rich.gg/fuzo/)

cheers guys ^^

---

<div class="post-metadata">

**Author:** ![TfGuy44](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/tfguy44/32/41_2.png) [@TfGuy44](https://discourse.processing.org/u/TfGuy44)\
**Post date:** [June 15, 2018, 6:47pm UTC](https://discourse.processing.org/t/the-perspective-calculation/988/2 "2018-06-15T18:47:13Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![phoebus](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/phoebus/32/481_2.png) [@phoebus](https://discourse.processing.org/u/phoebus)\
**Post date:** [June 15, 2018, 8:05pm UTC](https://discourse.processing.org/t/the-perspective-calculation/988/3 "2018-06-15T20:05:29Z")

</div>

here is [what i see](https://rich.gg/assets/perspective_divide2.jpg)

---

<div class="post-metadata">

**Author:** ![phoebus](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/phoebus/32/481_2.png) [@phoebus](https://discourse.processing.org/u/phoebus)\
**Post date:** [June 16, 2018, 9:51am UTC](https://discourse.processing.org/t/the-perspective-calculation/988/4 "2018-06-16T09:51:47Z")

</div>

holy smoke !!

I found out that the proper calculation was

```auto
   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
