iDevGames Forums
Local (X, Y) Coordinates from 3D plane coordinates - Printable Version

+- iDevGames Forums (http://www.idevgames.com/forums)
+-- Forum: Development Zone (/forum-3.html)
+--- Forum: Game Programming Fundamentals (/forum-7.html)
+--- Thread: Local (X, Y) Coordinates from 3D plane coordinates (/thread-1819.html)



Local (X, Y) Coordinates from 3D plane coordinates - merrill541 - Feb 1, 2009 07:07 PM

Hello.
I was wondering if anyone knew how to get an (X, Y) 2D coordinate, from a 3D coordinate based on the plane the 3D coordinate was located on.
Assuming the origin would be at the point where the plane's normal hits the plane.


Local (X, Y) Coordinates from 3D plane coordinates - ThemsAllTook - Feb 1, 2009 08:02 PM

If I'm understanding your question correctly, it sounds like you'd want to perform a transformation on the 3D point to put it into a coordinate system where the plane is perpendicular to the Z axis. In my current project, I do that something like this:

Code:
Vector3 worldSpaceToPlaneSpace(Vector3 point, Vector3 planeNormal) {
    Vector3 front, cross;
    float angle;
    Quaternion planeTransformation;
    
    front = Vector_withValues(0.0f, 0.0f, 1.0f);
    cross = Vector_cross(planeNormal, front);
    angle = Vector_dot(planeNormal, front);
    if (angle < -0.9999f) {
        planeTransformation = Quaternion_fromAxisAngle(Vector_withValues(0.0f, 1.0f, 0.0f), M_PI);
    } else if (angle > 0.9999f) {
        planeTransformation = Quaternion_identity();
    } else {
        planeTransformation = Quaternion_fromAxisAngle(cross, acos(angle));
    }
    
    return Quaternion_multiplyVector(planeTransformation, point);
}

Supporting 3D math code:


Local (X, Y) Coordinates from 3D plane coordinates - Hog - Feb 2, 2009 03:46 AM

if you have a plane given 3 points a, b, c your plane space matrix would theoretically be something like: (b-a,c-a,(b-a)x(c-a),a). (if i haven't gotten the translation part all wrong). you basically need to invert that.


Local (X, Y) Coordinates from 3D plane coordinates - RhinosoRoss - Mar 10, 2009 06:57 AM

...So you have a point (the plane origin) and a vector (the plane normal), and another point which you imply is on the plane...

It seems to me that you're missing a vector on the plane to define it's rotation about its normal...

I'm guessing you've already projected the point to the plane, but just in case: that is:
PointOnPlane = Point - Normal * ((Point-Origin) dot Normal)
All coordinates there will be World Coordinates and it assumes the Normal is actually normalised.

To map to a plane's coordinate space, though you need to define an x and y direction on the plane as well as its normal. This is mostly done in a matrix which allows you to transform by multiplying the point with the matrix both ways.
A 4x3 matrix is all you need:
Code:
M[0]=dx.x; M[1]=dx.y; M[ 2]=dx.z; M[ 3]=-dx.Dot(PV.P);
  M[4]=dy.x; M[5]=dy.y; M[ 6]=dy.z; M[ 7]=-dy.Dot(PV.P);
  M[8]=dz.x; M[9]=dz.y; M[10]=dz.z; M[11]=-dz.Dot(PV.P);
Setting from the inverse lets you put in the origin directly:
Code:
I[0]=dx.x; I[1]=dy.x; I[ 2]=dz.x; I[ 3]=PV.P.x;
  I[4]=dx.y; I[5]=dy.y; I[ 6]=dz.y; I[ 7]=PV.P.y;
  I[8]=dx.z; I[9]=dy.z; I[10]=dz.z; I[11]=PV.P.z;

Set up the above array for the inverse, then call something like this:
Code:
bool SetFromInverse(const double* I) {
    if(I==0) {
      SetToIdentity();
      return false;
    }
    memcpy(Inverse, I, sizeof(Inverse));
    Matrix[0]=I[0]; Matrix[1]=I[4]; Matrix[ 2]=I[ 8];
    Matrix[4]=I[1]; Matrix[5]=I[5]; Matrix[ 6]=I[ 9];
    Matrix[8]=I[2]; Matrix[9]=I[6]; Matrix[10]=I[10];
    double Determinant=I[0]*(I[5]*I[10]-I[9]*I[6]) + I[4]*(I[9]*I[2]-I[1]*I[10]) + I[8]*(I[1]*I[6]-I[5]*I[2]);
    bool OK=(Determinant!=0);
    if(!OK) Determinant=2*DBL_MIN; // Avoid Divide by zero: needs <float.h>
    Matrix[ 3]=(I[1]*(I[7]*I[10]-I[6]*I[11]) + I[5]*(I[2]*I[11]-I[3]*I[10]) + I[9]*(I[6]*I[3]-I[2]*I[7]))/Determinant;
    Matrix[ 7]=(I[0]*(I[6]*I[11]-I[7]*I[10]) + I[4]*(I[3]*I[10]-I[2]*I[11]) + I[8]*(I[2]*I[7]-I[6]*I[3]))/Determinant;
    Matrix[11]=(I[0]*(I[7]*I[ 9]-I[5]*I[11]) + I[4]*(I[1]*I[11]-I[3]*I[ 9]) + I[8]*(I[5]*I[3]-I[1]*I[7]))/Determinant;
    return OK;
  }

and translate with something like this:

Code:
g3Point  TransformToPlane    (const g3Point& p) const {return Multiply(p,Inverse);}
  g3Point  TransformToGlobal   (const g3Point& p) const {return Multiply(p,Matrix );}
  g3Point  TransformToGlobal   (const g2Point& p) const {return Multiply(p,Matrix );}
  g3D Multiply(const g3D& d, const double m[12])  const
{return FlatLand ? d : g3D(
    m[0]*d.x+m[1]*d.y+m[ 2]*d.z+m[ 3],
    m[4]*d.x+m[5]*d.y+m[ 6]*d.z+m[ 7],
    m[8]*d.x+m[9]*d.y+m[10]*d.z+m[11]);
  }
  g3D Multiply(const g2D& d, const double m[12])  const
{return FlatLand ? g3D(d) : g3D(
    m[0]*d.x+m[1]*d.y+m[ 3],
    m[4]*d.x+m[5]*d.y+m[ 7],
    m[8]*d.x+m[9]*d.y+m[11]);
  }

LOL - I wonder if that was what you wanted or not?!


Local (X, Y) Coordinates from 3D plane coordinates - ultramcuaiam - May 26, 2009 09:29 AM

Hi RhinosoRoss

Code:
M[0]=dx.x; M[1]=dx.y; M[ 2]=dx.z; M[ 3]=-dx.Dot(PV.P);
  M[4]=dy.x; M[5]=dy.y; M[ 6]=dy.z; M[ 7]=-dy.Dot(PV.P);
  M[8]=dz.x; M[9]=dz.y; M[10]=dz.z; M[11]=-dz.Dot(PV.P);


I have problem with convert 2D-coordinate to 3D-coordinate.
I don't know dx, dy, dz and PV.P , what they means ?

Best Regards,
AIam Rasp


Local (X, Y) Coordinates from 3D plane coordinates - RhinosoRoss - Jun 29, 2009 01:32 AM

ultramcuaiam Wrote:Hi RhinosoRoss

Code:
M[0]=dx.x; M[1]=dx.y; M[ 2]=dx.z; M[ 3]=-dx.Dot(PV.P);
  M[4]=dy.x; M[5]=dy.y; M[ 6]=dy.z; M[ 7]=-dy.Dot(PV.P);
  M[8]=dz.x; M[9]=dz.y; M[10]=dz.z; M[11]=-dz.Dot(PV.P);


I have problem with convert 2D-coordinate to 3D-coordinate.
I don't know dx, dy, dz and PV.P , what they means ?

Best Regards,
AIam Rasp

Sorry, I just clipped some code: they're the plane's vectors and point...

To fully specify a plane, you need a point on the plane that is going to be the origin (PV.P), and three vectors: the normal (dz) and two vectors orthogonal to dz which are going to make up the cartesian axes for the plane.

The code is from The Nugget Mines.
The PV page has a lot of methods for plane handling (a PV is a point and vector together, in this case the origin and normal of a plane).