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.