Camera distance to 3D points in parallel projection

I have a central function that I use to project 3D {x, y, z} coordinates onto a 2D picture plane. For a number of reasons, I can’t use any of Processing’s 3D functionality for what I’m doing.

I’m hoping to find a way to depth sort all points so that I can then use a cropping function to remove anything that’s behind something else. In order to do that, I need to know the distance between each point and from the camera, and I don’t know where the camera is in {x, y, z}.

This is the simple function I’m using to project 3D points onto the 2D picture plane. It takes as inputs:
the point to project: float[] pos = {x, y, z}
rotation angle of the camera
elevation angle of the camera
x & y origin points

float[] project3to2(float[] pos, float rotation, float elevation, float orgX, float orgY) {
  float rot = rotation * (PI/180);
  float elv = elevation * (PI/180);
  
  float rX = cos(rot);
  float rY = sin(rot) * cos(elv);
  float fX = sin(rot);
  float fY = -cos(rot) * cos(elv);
  float upY = sin(elv);
  
  float pX = orgX + (pos[0] * rX) + (pos[1] * fX);
  float pY = orgY + (pos[0] * rY) + (pos[1] * fY) + (pos[2] * upY);
  
  float[] out = {pX, pY};
  return out;
};

Can anyone point me in the direction of determining the position of the camera/eye? This kind of math does not come natural to me.
I have all the other pieces in place, and I just need to automate the depth sorting before cropping.

Any help would be greatly appreciated.

1 Like

Replying to myself here.

Camera distance isn’t the best way to put it. Because this is orthographic/axonometric projection, there isn’t a singular viewpoint the way there would be with point perspective projection.

What I’m looking for is the distance from each point to be projected through the projection plane to the viewpoint plane.

Does that mean that your renderer is default (JAVA2D), or that you are using P2D, or that you are using P3D but placing everything in a fixed z?

Does that mean that you are using ortho()?

Do you mean that you don’t know the default location of perspective() as listed on the reference page,

perspective(fovy, aspect, zNear, zFar)

default:
perspective(PI/3.0, width/height, cameraZ/10.0, cameraZ*10.0) where cameraZ is ((height/2.0) / tan(PI*60.0/360.0));

…or do you mean that the perspective is changing at runtime and you don’t know it in general?

This question might be a bit less mysterious if you provided a minimal sketch, or at least your setup().

1 Like

Yeah, I think he does all in P2D and does the projections by hand…

Seeing the Sketch would help

Thanks for the responses.

as Chrisir guessed, I’m doing everything by hand. I’m creating and cropping line work, and because of that, none of the built-in 3D projection functionality completely suits my workflow from the Processing sketch onwards through my process.

I’ll try and strip what I’m doing down to a minimal example. It might take me until the morning to get that together.

1 Like

I made a quick semi-accurate illustration of what I’m talking about, and stripped down what I’m doing to a simple sketch example.

I need to figure out the depth order of lines in the scene, so that I can crop the lines in that order. It’s the Painter’s Algorithm problem.

I’m hoping that I can determine the distance from each {x, y, z} point, along the ground plane in line perpendicular to the orientation of the picture plane, to the vertically perpendicular point from the ground plane to the bottom edge of the picture plane. I hope that makes some sense.

That distance is shown by a red line in my illustration.

orthoExample

float rotationAngle = 40;
float elevationAngle = 60;
float xPush = 0;
float yPush = 0;
float[] all = {rotationAngle, elevationAngle, xPush, yPush};

void setup() {
  size(800, 800);
  noLoop();
}

float[] projOrtho(float[] pos, float[] globals) {
  float rot = globals[0] * (PI/180);
  float elv = globals[1] * (PI/180);
  
  float rX = cos(rot);
  float rY = sin(rot) * cos(elv);
  float fX = sin(rot);
  float fY = -cos(rot) * cos(elv);
  float upY = sin(elv);
  
  float pX = globals[2] + (pos[0] * rX) + (pos[1] * fX);
  float pY = globals[2] + (pos[0] * rY) + (pos[1] * fY) + (pos[2] * upY);
  
  float[] out = {pX, pY};
  return out;
};

void draw() {
  
  float sz = 100;
  
  for(int i=0; i<8; i++) {
    float[] pos = {i*sz, 0, 0};
    //I'M LOOKING FOR THE DISTANCE FROM THIS POINT TO THE BOTTOM EDGE OF THE PICTURE PLANE
    float[] pos3 = projOrtho(pos, all);
    ellipse(pos3[0], pos3[1], 20, 20);
  };
  
}
1 Like