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\$ Mar 17 '15 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
    Mar 17 '15 at 14:00

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.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.