0
104 Jan 03, 2009 at 11:34

How do you compute the distance of a ray starting from a position to hit an infinite plane.
I need to fit it in a shader too, so it has to be minimal, and what would the best way to describe a plane inside a shader?

#### 4 Replies

0
105 Jan 03, 2009 at 12:14

/////////////////////////////////////////////////
// intersection beetween plane and line
// returns point of intersection

void RayPlaneIntr( const Vec3f &A ,const Vec3f &B,
const Vec3f &P0,const Vec3f &N ,
Vec3f &Pi )
{
Vec3f D;
float t,denum;
D=B-A;
denum=dot( N,D );
if ( denum==0.0f )
denum=_VT_BSPEPSILON_;
t=dot( N,P0-A );
t/=denum;
Pi=A+t*D;
}

This is the function i use in my engine, to compute intersection point ,
you can easily substituite (sp??)
the Vec3f with a float[3] and the plane with a float[4] , think the rest is clear
If you want only the distance use this

///////////////////////////////////////////////
// distance from plane
// assumes plane is normalized

double DistanceFromPlane( const Vec3f&P ,
const Vec3f& P0,
const Vec3f& Normal )
{
return FastAbs ( dot ( P-P0, Normal ) );
}

By the way i have started a blog where i will put all of my 3d work
along with code snippets like that , and also more advanced stuff
for 3d engine programming, all free of charge of course

0
104 Jan 03, 2009 at 12:22

Thats a big help, but also i need calculate plane from 3 points, then id be right to get started.
Hang on, is that easy. just find the normal and use one of the points - does that work?

0
105 Jan 03, 2009 at 13:14

basically yes, this is a function i wrote compute plane normal(s) , just use what you need

/////////////////////////////////////
// compute normals ,edge normals ,
// center , area and volume

bool ComputeNormals( CSurface *Surface,
Vec3f V0, Vec3f V1,Vec3f V2 )
{
if ( Surface==NULL )
return false;

/////////////////////////////////////
// normal

Vec3f u,v;

u=V1-V0;
v=V2-V0;

Surface->Normal=cross(u,v);
Surface->Normal.normalize();
Surface->D0=-dot( Surface->Normal,V0 );

//////////////////////////////////////////////
// compute edge normals

Vec3f p,n1,n2,n3;

//////////////////////////////////////////////
// compute first edge normal

p=V0+Surface->Normal ;
u=p-V0;
v=V2-V0;
Surface->EdgeNormal1=cross(u,v);
Surface->EdgeNormal1.normalize();

//////////////////////////////////////////////
// compute second edge normal

p=V1+Surface->Normal ;
u=p-V1;
v=V0-V1;
Surface->EdgeNormal2=cross(u,v);
Surface->EdgeNormal2.normalize();

//////////////////////////////////////////////
// compute third edge normal

p=V1+Surface->Normal ;
u=p-V2;
v=V1-V2;
Surface->EdgeNormal3=cross(u,v);
Surface->EdgeNormal3.normalize();

////////////////////////////
// compute center

Surface->Center=(V0+V1+V2)/3.0f;

////////////////////////////
// compute area and volume

u=V1-V0;
v=V2-V0;

p= cross ( u,v );

///////////////////////////
// compute area

Surface->Area= 0.5f *sqrt ( p.length() ) ;

//////////////////////////////
// compute volume

Surface->Volume =dot(V0,cross(V1,V2));

return true;
}

0
102 Jan 03, 2009 at 13:24

This one is old, but still works:

//
// Plane from three vertices
//
void CPlane::Determine(CVector *v1, CVector *v2, CVector *v3)
{
CVector Normal = CMath3D::Normal(v1,v2,v3);

m_fA = Normal.x;
m_fB = Normal.y;
m_fC = Normal.z;

// Ax + By + Cz - D = 0  ==>
// Ax + By + Cz = D
m_fD = m_fA*v2->x + m_fB*v2->y + m_fC*v2->z;
}


Normal is computed by:

//
// Normal of three vectors
//
CVector CMath3D::Normal(const CVector *v1, const CVector *v2, const CVector *v3)
{
CVector vt1;
vt1.x = v2->x - v1->x;
vt1.y = v2->y - v1->y;
vt1.z = v2->z - v1->z;

CVector vt2;
vt2.x = v3->x - v2->x;
vt2.y = v3->y - v2->y;
vt2.z = v3->z - v2->z;

CVector Normal = CrossProduct(&vt1,&vt2);

//
// Normalize normal vector
//

float fLen = (float)sqrt(Normal.x*Normal.x + Normal.y*Normal.y + Normal.z*Normal.z);

if (fLen == 0) fLen = 1;

Normal.x /= fLen;
Normal.y /= fLen;
Normal.z /= fLen;

return Normal;
}


CVector is a basic x,y,z class. I think it may be relatively easy to translate into shader code, as it has built-in support for normals and vectors, so you just need to translate the logic.

Hope this helps as well.