Ray-Plane功能不准确

时间:2013-04-13 05:04:42

标签: raytracing plane

我正在使用opengl在c ++中制作3D应用程序,并且希望在鼠标经过它们时突出显示。问题是,我已经有了这个工作,但是射线平面的交叉点确实是不准确的(例如,突出显示距离鼠标60像素的平面)。

我已经确定鼠标点和远点(方向)是准确的,所以问题在于射线平面功能。这是:

CODE:

// Casts a Ray from the start point in the direction of the direction vector. 
// Returns true of the plane is intersected 
// the 4 vector3ds are each point of the plane (quad)
bool rayplane(float nx, float ny, float nz, // normals coord
          float xs, float ys, float zs, // start point
          float xd, float yd, float zd, // direction vector
          vector3d p1, vector3d p2, vector3d p3, vector3d p4, float* dist, vector3d* point)
{
float a = xd*nx+yd*ny+zd*nz;
if (a == 0)
    return false;

    float t = ((p1.x*nx+p1.y*ny+p1.z*nz-nx*xs-ny*ys-nz*zs)/a);
if (t < 0)
    return false;
float x = xs + t*xd;
float y = ys + t*yd;
float z = zs + t*zd;
vector3d cp(x,y,z);

if (abs(trianglearea(p1,p3,p4)-trianglearea(p1,p4,cp)-trianglearea(p1,p3,cp)-trianglearea(p3,p4,cp))<0.0001 ||
    abs(trianglearea(p1,p2,p3)-trianglearea(p1,p2,cp)-trianglearea(p2,p3,cp)-trianglearea(p1,p3,cp))<0.0001)
{
    if (dist != NULL)
    {
        (*dist) = t;
        if (point != NULL)
        {
            point->x = x;
            point->y = y;
            point->z = z;
        }
    }
    return true;
}
return false;
}

以下是该函数的使用方法(在2d数组中每个平面的循环中使用):

if (rayplane(0.0, 1.0, 0.0, mousePosNear.x, mousePosNear.y, mousePosNear.z, 
                            mousePosFar.x, mousePosFar.y, mousePosFar.z, vector3d(0.0 + i, 0.0, 0.0 + j), 
                                                                        vector3d(1.0 + i, 0.0, 0.0 + j), 
                                                                        vector3d(1.0 + i, 0.0, 1.0 + j), 
                                                                        vector3d(0.0 + i, 0.0, 1.0 + j)))
{
    ...Do stuff
}

三角函数:

float trianglearea(vector3d p1, vector3d p2, vector3d p3)
{
float a = sqrt((p2.x-p1.x)*(p2.x-p1.x)+(p2.y-p1.y)*(p2.y-p1.y)+(p2.z-p1.z)*(p2.z-p1.z));
float b = sqrt((p3.x-p2.x)*(p3.x-p2.x)+(p3.y-p2.y)*(p3.y-p2.y)+(p3.z-p2.z)*(p3.z-p2.z));
float c = sqrt((p1.x-p3.x)*(p1.x-p3.x)+(p1.y-p3.y)*(p1.y-p3.y)+(p1.z-p3.z)*(p1.z-p3.z));
float s = (a+b+c)/2;
return (sqrt(s*((s-a)*(s-b)*(s-c))));
}

mousePosNear和mousePosFar坐标与3d世界中的鼠标完全一致,所以它们不是问题。

非常感谢帮助!

0 个答案:

没有答案