How do I map a 2D set of points to 3D-perspective correction

Get help using Construct 2

Post » Tue Nov 04, 2014 8:52 pm

I have mapped the red ball of the bottom top-view 2D table onto the top pseudo-3D table using essentially linear interpolation of the points. The red ball's X position on the 3D table is accurate. The *y* coordinate however is very wrong. See the ball on the 3D table isn't nowhere near the pharaoh's feet.

From what I gather, I need to take Z into account somehow, but I don't know how.
If anyone ( @r0j0hound ?) has any ideas? I don't need texture mapping, just coordinate mapping.

Thank you


Here is my .capx
https://dl.dropboxusercontent.com/u/280 ... pping.capx

Image
B
28
S
12
G
4
Posts: 193
Reputation: 4,581

Post » Tue Nov 04, 2014 9:03 pm

it's hard to describe this in text, but you need to define you angle of perspective... then by trigonometry you'll be able to map your points.
the x co-ordinate in your example is fine as it does not change no matter what you do, but as you said y/z are a different. it is called 3D projections so feel free to google that term.

so think of it this way ... look at a wire-frame box.. as you move your perspective from looking in at the box on one face and up and over.. x doesn't change, but you'll see some combination of the original face and now another face.. that gives you a bigger space.. and how it contributes to a final co-ordinate depends on the degree of rotation you've done.

if I may suggest Wikipedia... it has a good description, just remember you're keeping one axis constant, so it becomes a lot simpler than what is described here/
http://en.wikipedia.org/wiki/3D_projection

perspective (where far away things look smaller than near things) is again a case of trig, but too complex to describe here
B
7
S
3
G
1
Posts: 184
Reputation: 1,352

Post » Tue Nov 04, 2014 9:33 pm

@rho thank you for the rapid response!

Unfortunately I haven't been able to understand vector math too well, and the wikipedia article is way above my league. I just intuitively know I should factor in Z somewhere in my calculations of the Y' coordinate of the ball on the 3D table.
Maybe I'm not smart enough for this
B
28
S
12
G
4
Posts: 193
Reputation: 4,581

Post » Tue Nov 04, 2014 9:56 pm

x = centerX + cos(angle) * distance
y = centerY + sin(angle) * distance
z = centerZ + sin(angle) * distance

Just think of z as another y, another plane, that works just like the y, except it intersects x, and y, ...oh and scales in size as it gets larger, and closer to the center.
Image ImageImage
B
169
S
50
G
170
Posts: 8,292
Reputation: 108,728

Post » Tue Nov 04, 2014 10:56 pm

This may work:
In it's basic form a perspective projection in just dividing x and y by z.
Code: Select all
This is the 2d map.
o1 is the top-left corner and p is a point to project.

   w
o1----+
|     |
| p   |h
|     |
+-----+



Convert them to u and v to get coordinates from 0-1
u=(p.x-o1.x)/w
v=(p.y-o1.y)/h

Next we have the perspective sprite.  w1 and w2 are the widths of the top and bottom. o2 is the top-left and h2 is the height.
      w1
o2  ______     -+
   /      \     |
  /        \    | h2
 /          \   |
/____________\ -+
      w2

We find the z from v with:
z = w2/lerp(w1, w2, v)

Then we can do the perspective transform with:
screenx = ((u-0.5)/z + 0.5)*w2 + o2.x
screeny = ((v-0.5)/z + 0.5)*h2 + o2.y
B
92
S
32
G
107
Posts: 5,280
Reputation: 69,971

Post » Wed Nov 05, 2014 3:33 am

Thank you everyone. @newt this seems to be over my head too :/

@r0j0hound always a step ahead.
This actually produces very weird results:
https://dl.dropboxusercontent.com/u/280 ... ping2.capx

There is some 3D projection going on, (drag and drop the ball to see), but it's not right at all.

So your calculation of Z gives

Z= w2/w1 when V=0 and Z= w2/w2 when V=1

So Z is from 1 (nearest) to about 1.7 in this case. Why? What does this number represent?

Follow up questions:
1.Why do you calculate Z like that?

2. Why are we dividing (u-0.5) /z ?

Thank you for taking the time everyone. Please let me know if I can pixel something for you in return <3
B
28
S
12
G
4
Posts: 193
Reputation: 4,581

Post » Wed Nov 05, 2014 4:13 am

I didn't test it so there may be errors. Also I can't look at the capx till tomorrow.

Z is the distance from the eye, which is at z=0. The camera is at z=1. Anything further will have a greater z which in turn will look smaller since the perspective is calculated with x/z, y/z. Basically the bottom width divided by 1.7 should equal the top width.

1. The idea I had was to find how far away the back edge would have to be if it was that width. Without perspective the top edge should be just as wide as the bottom. With perspective the same projection formula can be used proj_width=width/z. Sovlving for z it come out to z=proj_width/width, and then it's just a matter of interpolating by y or v.

2. The 0.5 is so we're scaling at the center instead of the left edge. U and v are in the range of 0 to 1, so 0.5 is halfway. Also /z is scaling.
As a simple example say you wanted to double the x distance from 320 you'd do:
X=(x-320)*2+320 if instead we wanted to just scale from 0 it would be
X=x*2
B
92
S
32
G
107
Posts: 5,280
Reputation: 69,971

Post » Wed Nov 05, 2014 5:06 pm

@christina
Here is a capx with the idea I posted. The only error was "screeny = ((v-0.5)/z + 0.5)*h2 + o2.y" needed to be changed into "screeny = (v/z)*h2 + o2.y".
https://dl.dropboxusercontent.com/u/542 ... sform.capx
I tested it with a plane rendered with two different field of views and it seems to become less accurate if I use a fov other than 60. It probably needs to account for that somehow.

Your last capx isn't working right because it's it's scaling from the left instead of the center. See 2 above^

Also for your original capx changing the set y expression to "board.Y + (relativeY*board.Height) /lerp(2,1,relativeY)" seems to get the y working better. You can adjust 2 to change the strength of the effect.
B
92
S
32
G
107
Posts: 5,280
Reputation: 69,971

Post » Wed Nov 05, 2014 7:01 pm

@r0j0hound I just logged in to tell you you're absolutely right about the Y axis, that's totally the way to go! And I fixed the X axis calculation like you did.

And thank you *so* much for taking the time to make a capx <3
I owe you lots, and we all do.
B
28
S
12
G
4
Posts: 193
Reputation: 4,581

Post » Sun Nov 09, 2014 12:50 am

@r0j0hound Just a quick untested thought, maybe we can get the FOV into account by using a "scaling" var, like this:

scaling = (x_resolution/2) / tan(fov_angle/2).

Then we use

y = (y_world * scaling) / z
B
28
S
12
G
4
Posts: 193
Reputation: 4,581

Next

Return to How do I....?

Who is online

Users browsing this forum: NN81, ultrafop and 31 guests