1
\$\begingroup\$

I am trying to implement a perspective view in a 2D soccer game, such like Nintendo World Cup. In this case, the soccer pitch will look like a isosceles trapezoid, but not a rectangle in real.

Here is my solution:

  1. I separate the game logic location and the final rendering location. In the game logic part, the pitch is still a rectangle, so we can make easy collision detection, player area change, out-of-bound checks, goal check, etc.. Just like an answer to Stack Overflow question Implement a projectile motion and collision detection - response in a 2D top-down game said:

  2. Then I just project players', ball's location into final screen location, so that player can fit in pitch (because the exact pitch image is a trapezoid like the screenshot) screenshot

I tried to do like that post said, but the result is wired, so I am thinking do I need to make a perspective projection like in a 3D game, but I do not know how. A 3D perspective projection needs to know the camera position, camera angle, near plane, but these do not exist in a 2D game.

How do I solve this problem?

\$\endgroup\$
3
  • \$\begingroup\$ The outer border is ok, the others are not. The 5m and the 16m as well the circle are not shrinking in the distance. \$\endgroup\$
    – ott--
    Commented Sep 26, 2013 at 17:02
  • \$\begingroup\$ Are you drawing the 5m and 16m as lines or as sprites? It will take some math to figure out the proper shape of a circle in a projected plane, but with sprites you can just scale the texture coordinates. \$\endgroup\$
    – Mokosha
    Commented Sep 27, 2013 at 0:28
  • \$\begingroup\$ now just simple line.Sorry,I don't get your points.I do not have problem on drawing the tilt pitch, I got problem on how to transform player and ball location to fit the pitch. \$\endgroup\$
    – Captain
    Commented Sep 27, 2013 at 1:13

1 Answer 1

2
\$\begingroup\$

The 2D coordinate system that describes your field can be parameterized the same way as your trapezoid.

Think about it this way... First let's label the corners of the field in the unprojected space:

  • TR: top-right
  • BR: bottom-right
  • TL: top-left
  • BL: bottom-left

Each of these corners has an x and y value, with BL== (0, 0) most likely. A good sanity check is to make sure that

TR.x - TL.x == BR.x - BR.y
TR.y - BR.y == TL.y - BR.y

In order to take some coordinate (x, y) from the unprojected field into the projected field, the easiest way to do this is to first figure out how far away from the bottom left corner of the field it is. In other words, we would like to find (t.x, t.y) such that

x == t.x + BL.x
y == t.y + BL.y

Ok, once we've figured out our vector t = (t.x, t.y) we can write them in the coordinate space of the rectangle itself. In other words imagine that BL is at the origin (0, 0), and TR is at the point (1, 1), then both t.x and t.y are somewhere in that square and belong to the interval [0, 1]. We can use a simple trick to transform our coordinates into this space:

tr.x = (t.x - BL.x) / (BR.x - BL.x)
tr.y = (t.y - BL.y) / (TL.y - BL.y)

Now, both tr.x and tr.y should be between 0 and 1. We call tr the parametric representation of the point (x, y) in the space of the rectangle, or unprojected soccer field, in this case. We know exactly where any point (x, y) is by using two coordinates between 0 and 1.

I still haven't mentioned how to go to the projected space. Once you have your parameterization, going to any shape that has four corners is easy. You have to map the four corners of your new shape to the four corners of your old shape. In this case, you have the parameterization for your old shape, so you simply need to remap it to the new projected trapezoid.

Let's say that your trapezoid has corners labeled:

  • tTR: trapezoid top-right
  • tBR: trapezoid bottom-right
  • tTL: trapezoid top-left
  • tBL: trapezoid bottom-left

In order to retrieve the projected coordinate of (x, y), you can simply bilinearly interpolate between each of the corners of the trapezoid:

bottom = (tBL)*(1 - tr.x) + (tBR)*tr.x
top = (tTL)*(1 - tr.x) + (tTR)*tr.x
final = bottom*(1 - tr.y) + top*tr.y

final should be a 2D coordinate within the trapezoid that corresponds to the same point in your logical field.

\$\endgroup\$
2
  • \$\begingroup\$ I can understand all you said before the final project equation, but What is the bottom and top in last three equations? \$\endgroup\$
    – Captain
    Commented Sep 30, 2013 at 13:35
  • \$\begingroup\$ You can think of bottom and top as "how far along the bottom and top edge do I need to go to then start moving in the y direction?" You can do this by figuring out how far along in the x direction you went in the unprojected space, and then going a proportional amount in the projected space. Remember, the tTR etc points are all 2D coordinates, which can be thought of as 2D vectors from the origin. \$\endgroup\$
    – Mokosha
    Commented Sep 30, 2013 at 13:39

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .