我正在使用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世界中的鼠标完全一致,所以它们不是问题。
非常感谢帮助!