Say I have a plane specified by a normal vector and point on the plane.

I want to specify a 2-D co-ordinate system that lies 'across' the plane, and then use that to find the 2-dimensional distance between any given points on that plane.

I want to do this so that I can specify scaled texture UV co-ordinates on an arbitrary plane. I will use the average centre of all points on the plane (the barycentre?) as UV: 0,0, and then I need a way to determine the 2-dimensional UV value for each point, subsequently.

Here's an example of what I'm trying to do:

enter image description here

The points in bright green are supplied as the inputs, those are the values I'm trying to work out. The dark green is the calculated mean-average centre (the image isn't exactly to scale), and should act as UV: 0,0.

A friend suggested that I take (firstPoint - centrePoint).ToUnit() as my 'x-axis' and then xAxis.Cross(planeNormal) as my 'y-axis'. That seems like a good place to start, but I'm unsure how to use these values to get X/Y co-ordinates for each point.

I don't care what the 'plane-local' X/Y axes are as long as they're the same for each vertex on the plane. I can rotate them in-editor later to make the right alignment manually anyway (I don't think there's any good way to programmatically select a 'default').

  • \$\begingroup\$ You need to solve p = u * axisX + v * axisY + center; for u and v. \$\endgroup\$ Commented Mar 17, 2015 at 13:22
  • 1
    \$\begingroup\$ You're right that there's no 100% consistent way to select a default orientation, thanks to that best-named result in geometry, the Hairy Ball Theorem. But you can get a decent compromise for most purposes - by choosing your yAxis = (0, 1, 0) - normal.y * normal (so the "v" direction aligns with world 'up' when possible), and choosing a fallback if that vector is "too close" to zero (ie. the plane is nearly horizontal), like yAxis = (0, 0, 1) - normal.z * normal; in either case normalize the vector once you're done, and set xAxis as the cross product of yAxis with the normal. \$\endgroup\$
    – DMGregory
    Commented Mar 17, 2015 at 14:00

1 Answer 1


You're on the right track. The method you describe gives an orthonormal basis for the plane, xAxis & yAxis.

Now for any arbitrary point on (or off) the plane,

  offset = point - center
  uv = scale * (dot(offset, xAxis), dot(offset, yAxis))

You can also express this operation as a matrix multiplication if you prefer. It's an orthographic projection onto your plane.


You must log in to answer this question.

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