Bay 12 Games Forum

Please login or register.

Login with username, password and session length
Advanced search  

Author Topic: An Artsy Question About Perspective And Math  (Read 3548 times)

Pnx

  • Bay Watcher
    • View Profile
An Artsy Question About Perspective And Math
« on: February 23, 2014, 09:42:56 pm »

So there's this whole big question that's been bothering me for ages, and it's go to do with perspective.
Spoiler (click to show/hide)
So this is a weird wireframe perspective thing I hacked together for funsies. And there's one thing that almost immediately started bothering me about it, it's that the distance between the "rungs" of the boxes is uneven as all hell. Now I know I can improve it and make them more accurate by eyeballing it, and adjusting until it feels better. But I find myself wondering something I've been wondering ever since I learned to do perspective drawings. Is there a better way to figure out how large something should appear?

I mean, I know about the inverse square law, and that if an object is twice the distance away from the viewer as another object it should appear 1/4th the size... but I'm sort of struggling to see an equation of some sort that could tell me how large something needs to appear relatively... and how would you go about exploiting this specifically?

Does anyone think they can lend me some insight?
Logged

Svampapa

  • Bay Watcher
    • View Profile
Re: An Artsy Question About Perspective And Math
« Reply #1 on: February 24, 2014, 10:29:39 am »

Don't forget to factor in the rounding of the earth.  :P

Have you taken linear algebra yet? Because I'm pretty sure the answer to your question involves lots of matrix and vector math.


Wikipedia on projections

Edit:
Perhaps this is a better link:
OpenGL projection matrix



« Last Edit: February 24, 2014, 10:35:35 am by Svampapa »
Logged

LeoLeonardoIII

  • Bay Watcher
  • Plump Helmet McWhiskey
    • View Profile
Re: An Artsy Question About Perspective And Math
« Reply #2 on: February 24, 2014, 02:39:04 pm »

Does it have to do with how you're centering it? Like, if you want the gaps between boxes to be even then they need to be even on the opposite side too.
Logged
The Expedition Map
Basement Stuck
Treebanned
Haunter of Birthday Cakes, Bearded Hamburger, Intensely Off-Topic

winner

  • Bay Watcher
    • View Profile
Re: An Artsy Question About Perspective And Math
« Reply #3 on: February 24, 2014, 03:23:16 pm »

what you want is a logarithmic scale. like on a slide rule.
With a logarithmic scale the proportions stay constant as you move along it making it look like equal intervals.
« Last Edit: February 24, 2014, 03:35:57 pm by winner »
Logged
The great game of Warlocks!

Pnx

  • Bay Watcher
    • View Profile
Re: An Artsy Question About Perspective And Math
« Reply #4 on: February 24, 2014, 11:46:21 pm »

Don't forget to factor in the rounding of the earth.  :P

Have you taken linear algebra yet? Because I'm pretty sure the answer to your question involves lots of matrix and vector math.


Wikipedia on projections

Edit:
Perhaps this is a better link:
OpenGL projection matrix
No, I haven't taken linear algebra... though I think at this point I really may want to.

So if I gather what they're saying in the OpenGL link correctly, they're assuming a certain point behind the screen is the viewing point, and then they're using the similar triangles rule to figure out where a given coordinate point should appear on the screen?

That's about the end of where my comprehension of that is really, if that's even right. Which is a shame because I really want to understand this stuff better.

Does it have to do with how you're centering it? Like, if you want the gaps between boxes to be even then they need to be even on the opposite side too.
Basically there's this property of spacial geometry where any and all lines that are parallel in real space will appear to be approaching the same point when viewed. This point being what they call a vanishing point. It's sort of a cheap hack honestly, but it allows us to create the illusion of a 3D landscape pretty effectively. What I'm talking about here is that the spacing between the boxes shown there seems pretty even at first glance, but anyone with some grasp of spaces can tell that in the 3D space depicted the boxes are spaced out in a very uneven way indeed.
Logged

Urist McScoopbeard

  • Bay Watcher
  • Damnit Scoopz!
    • View Profile
Re: An Artsy Question About Perspective And Math
« Reply #5 on: February 25, 2014, 12:07:35 am »

Honestly, im not sure what your problem is. There isn't anything wrong with the boxes as far as I can see.

If your problem is scale then you either have to include some sort of reference, like a human figure or distance measure, or assume people will get it, like if your drawing buildings with average sized doors, etc.

Now said something about rungs on boxes, assuming you want them to appear equally spaced within the picture, you'd have to have the become gradually closer as they get closer to the vanishing point.

Hope that helps.
Logged
This conversation is getting disturbing fast, disturbingly erotic.

Killjoy

  • Bay Watcher
    • View Profile
Re: An Artsy Question About Perspective And Math
« Reply #6 on: February 25, 2014, 02:15:16 am »

Quote
No, I haven't taken linear algebra... though I think at this point I really may want to.
Linear algebra is a VERY big subject, you need to learn about linear equation, linear algebra arithmetic and linear transforms specifically. It should be enough to understand the article. I am assuming you know a little bit about classical analytically geometry (High school geometry).

Quote
So if I gather what they're saying in the OpenGL link correctly, they're assuming a certain point behind the screen is the viewing point, and then they're using the similar triangles rule to figure out where a given coordinate point should appear on the screen?
It is because the z coordinate is flipped between the eye coordinates and the NDC.
Logged
Merchants Quest me programming a trading game with roguelike elements.

zombie urist

  • Bay Watcher
  • [NOT_LIVING]
    • View Profile
Re: An Artsy Question About Perspective And Math
« Reply #7 on: February 25, 2014, 02:16:48 am »

A perspective transformation maps a point in 3d point to another 3d point.

Since this is linear, you can represent the transform as a matrix. So you have a point X and your perspective transformation A, then the mapped point is AX. Since A is size 3x3 and X is size 3x1, the resulting vector is also size 3x1, but the z-coord will be fixed and equal to how far your eyes are away from the screen.

If you want a more in depth description, I can type something up about how to find these matrices and stuff later.
Logged
The worst part of all of this is that Shakerag won.

MagmaMcFry

  • Bay Watcher
  • [EXISTS]
    • View Profile
Re: An Artsy Question About Perspective And Math
« Reply #8 on: March 09, 2014, 02:42:43 pm »

Okay, hold up everyone.

Neither this
if an object is twice the distance away from the viewer as another object it should appear 1/4th the size...
nor this
what you want is a logarithmic scale.
is true. Nor this
A perspective transformation maps a point in 3d point to another 3d point.
or this.
Since this is linear, you can represent the transform as a matrix. So you have a point X and your perspective transformation A, then the mapped point is AX. Since A is size 3x3 and X is size 3x1, the resulting vector is also size 3x1, but the z-coord will be fixed and equal to how far your eyes are away from the screen.

Let's start with the basics. First, we'll need a camera focus point, a point where all light rays go through. For simplicity's sake, let's make this point the origin.

Next, we need a canvas we'll paint the image upon, by pretending to fire light rays from all the objects in the scene directly at the camera, and painting the spot where each light ray intersects the canvas. Now if you would go and put your face where the camera is and look at the canvas, you'd see exactly the same as what you'd see if the canvas wasn't there. In our example, let's make the canvas the plane of all points (x, y, z) with z=1, which a horizontal plane directly above the camera.

Now let's look at any line passing through the origin. For every two points (x, y, z) and (x', y', z') on the same line through the origin, x/x' = y/y' = z/z'. We can use this to find out the intersection of the light beam with the canvas: Let's pick a random point (x, y, z) and throw a light at the canvas, and let's call the image point (x', y', z'). We know that z' = 1, so we know that x/x' = y/y' = z/z' = z/1 = z, therefore x' = x/z and y' = y/z. Our final image point is (x/z, y/z, 1). There, that's literally everything you have to do in this situation: divide everything by z. And there you go, x/z and y/z are your screen coordinates (you don't need the 1). Map them to pixels and you're done.

Here's the transformation function: (x, y, z) -> (x/z, y/z).

Now let's talk about moving objects in 3D space, because that's what you're going to do to the camera (actually you'll do it to everything else instead).

Let's say you want to move a point at (x, y, z) by the vector (x°, y°, z°). To do that, just add the vector to the point.

Here's the translation function: (x, y, z) -> (x+x°, y+y°, z+z°).

Let's say you want to rotate a point around the x-axis by the angle α. Instead of doing that, you can just rotate your object around the x-axis by the angle -α.

Here's the rotation function for rotation around the x-axis: (x, y, z) -> (x, y*cos(α)-z*sin(α), y*sin(α)+z*cos(α)).
Here's for the y-axis: (x, y, z) -> (z*sin(α)+x*cos(α), y, z*cos(α)-x*sin(α)).
Here's for the z-axis: (x, y, z) -> (x*cos(α)-y*sin(α), x*sin(α)+y*cos(α), z).

Now let's look at a camera like one you'd find in a normal first-person 3D game. This camera needs five position variables: x°, y°, z°, pitch and yaw. The position coordinates are self-explanatory, the other two define the camera's view direction. The pitch is the angle from up, and the yaw is the angle from north.

To move the camera from the origin to its correct position like any normal person, you'd

* translate the camera by (x°, y°, z°),
* then rotate it about the z-axis by the yaw,
* then rotate it about the x-axis by the pitch.

Instead of moving the camera to that position, we'll just move all the points by the opposite movement instead. To do this, we'll need to do these same steps to the objects, but by the opposite amounts, and more importantly in the opposite order. So you'd

* rotate the object about the x-axis by negative the pitch,
* then rotate it about the z-axis by negative the yaw,
* then translate the resulting object by (-x°, -y°, -z°).

Here's your complete camera transformation process:
Code: [Select]
void getCanvasCoordsfromPointCoords(float pointX, float pointY, float pointZ, float camX, float camY, float camZ, float pitch, float yaw, float& cvX, float& cvY) {
  float x1 = objX, y1 = pointY*cos(pitch)+pointZ*sin(pitch), z1 = -pointY*sin(pitch)+pointZ*cos(pitch);
  float x2 = x1*cos(yaw)+y1*sin(yaw), y2 = -x1*sin(yaw)+y1*cos(yaw), z2 = z1;
  float x3 = x2-camX, y3 = y2-camY, z3 = z2-camZ;
  cvX = x3/z3;
  cvY = y3/z3;
}
Finally, you may want to transform those screen coordinates to pixels.
Code: [Select]
void getPixelCoordsFromCanvasCoords(float cvX, float cvY, float ssX, float ssY, float c, float& posX, float& posY) {
  posX = (c*cvX+ssX/ssY)*ssY/2;
  posY = (c*cvY+1)*ssY/2;
}
This transforms your canvas position (cvX, cvY) into a screen position (posX, posY). Note that ssX and ssY need to be the pixel dimensions of your screen, and that c is the scale of the transformation (to be precise, c=cot(FoV/2)), and for best results it should be around 1 or so.
« Last Edit: March 09, 2014, 02:44:50 pm by MagmaMcFry »
Logged

DreamThorn

  • Bay Watcher
  • Seer of Void
    • View Profile
    • My game dev hobby blog (updates almost never)
Re: An Artsy Question About Perspective And Math
« Reply #9 on: March 10, 2014, 06:38:17 am »

Essentially, what you want is to have the ratio of the distance between successive lines to remain constant:

If the first line is at 100 pixels from the equator and the second line is at 90 pixels, the ratio is 0.9
So the third line is at 0.9 * 90 = 81
The fourth line is at 0.9 * 81 = 72.9
65.6
59.0
53.1
etc.

B.t.w. there will be an infinite number of lines if you are on an infinite plane.  On a sphere it would be more complicated, but noone ever does that. ;)
Logged
This is what happens when we randomly murder people.

You get attacked by a Yandere triangle monster.

MagmaMcFry

  • Bay Watcher
  • [EXISTS]
    • View Profile
Re: An Artsy Question About Perspective And Math
« Reply #10 on: March 10, 2014, 07:38:22 am »

Essentially, what you want is to have the ratio of the distance between successive lines to remain constant:
Nope, wrong.
Here's a comparison for your convenience:
Spoiler (click to show/hide)
On the left, you see your own idea. Notice how the panels appear to be farther apart further away.
On the right, you see the correct version. The apparent panel sizes follow a harmonic progression instead of an exponential one.
Logged

DreamThorn

  • Bay Watcher
  • Seer of Void
    • View Profile
    • My game dev hobby blog (updates almost never)
Re: An Artsy Question About Perspective And Math
« Reply #11 on: March 10, 2014, 07:50:04 am »

I seem to have made an error.

Recalculating...

Answer:

The simple rule is that the ratio between the length of the drawn line and its full length is equal to the ratio between the distance to the image and the distance to the line from the PoV.

Calculating a sequence from two points that you have already chosen is a quite a chore, though.
Assuming the lines are parallel to the picture-plane:

y[n] = L / (z[1] + (n-1)*d)

y[n] is the length of the nth line of the sequence, measured on the picture-plane.
L is the distance from your PoV to the floor.
d is the distance between successive lines.
z[1] is the distance between your PoV and the point indicated by the intersection of the first line and the horizon.

Comparing y[1] with y[2], followed by too much algebra, will give you L, d and z[1], which you then use to calculate y[3] etc.
« Last Edit: March 10, 2014, 08:41:17 am by DreamThorn »
Logged
This is what happens when we randomly murder people.

You get attacked by a Yandere triangle monster.