Could someone please help me with a problem?
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?
ray distance to plane
Started by rouncer, Jan 03 2009 11:34 AM
4 replies to this topic
#1
Posted 03 January 2009 - 11:34 AM
#2
Posted 03 January 2009 - 12:14 PM
/////////////////////////////////////////////////
// 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
http://www.vp8671.blogspot.com/
// 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
http://www.vp8671.blogspot.com/
#3
Posted 03 January 2009 - 12:22 PM
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?
Hang on, is that easy. just find the normal and use one of the points - does that work?
#4
Posted 03 January 2009 - 01:14 PM
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;
}
/////////////////////////////////////
// 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;
}
Check my code in the c/c++ section :
http://www.binpress.com/browse/c
http://www.binpress.com/browse/c
#5
Posted 03 January 2009 - 01:24 PM
This one is old, but still works:
Normal is computed by:
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.
//
// 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.
1 user(s) are reading this topic
0 members, 1 guests, 0 anonymous users












