检查射线与立方体相交的问题



我现在被我的RubiksCube项目卡住了。

我想要实现的:左键检查是否单击了单个Mini-Cubie。(点击立方体时可能会旋转)

其他魔方类的代码工作正常。我们需要用数学公式自己计算这些函数。

当前问题:

  • 未检测到点击边缘
  • 在旋转后点击某一点有时会导致:错误的图层被标记为已点击或没有图层被标记为已点击

我的总体想法是保护每个图层的4个角点的坐标,在旋转时更新它们的位置,并在这些位置的帮助下检查光线的交叉点

void MergedCube::Render(float aspectRatio)
{
m_viewProject = glm::perspective(glm::radians(45.0f), aspectRatio, 0.1f, 100.0f) *
glm::lookAt(glm::vec3(0.0f, 0.0f, -9.0f), 
glm::vec3(0.0f), 
glm::vec3(0.0f, 1.0f, 0.0f)) *
glm::mat4_cast(m_orientationQuaternion);
compound = glm::translate(m_viewProject, (glm::vec3(1, 1, 1) - 1.0f));
m_cubieRenderer.Render(compound);

// Calling LayerCalculation() for every Layer with direction -1 or 1

}

这个方法应该计算我的辅助向量,两个方向向量和各层的归一化向量

void MergedCube::LayerCalculation(std::vector<glm::vec3>& points, int normDirection) {
while (points.size() > 4) {
points.erase(points.end()-1);
}
glm::vec3 middlePoint = (points[0] + points[2]) / 2.0f;
glm::vec3 firstPoint = (points[0] + points[1]) / 2.0f;
glm::vec3 secondPoint = (points[0] + points[3]) / 2.0f;
glm::vec3 vecA = glm::normalize(firstPoint - middlePoint);
glm::vec3 vecB = glm::normalize(secondPoint - middlePoint);

glm::vec3 normalVector = glm::cross(vecA,vecB) * glm::vec3(direction);
points.push_back(middlePoint);
points.push_back(vecA);
points.push_back(vecB);
points.push_back(normalVector); 

}

现在是RayAndCubeIntersection方法。

bool MergedCube::RayAndCubeIntersection(glm::vec3 startingPoint, glm::vec3 direction, 
std::vector<glm::vec3> Pts) {
glm::vec3 helperVec = pts[4];
glm::vec3 normVec = pts[7];
glm::vec3 directionVecA = pts[5];
glm::vec3 directionVecB = pts[6];
if (glm::dot(rayDirection, normVec) < 0) {
float res = normVec[0] * helperVec[0] + normVec[1] * helperVec[1] + normVec[2] * helperVec[2];
float directionMultiplikator = (res - normVec[0] * rayStartingPoint[0] - normVec[1] * rayStartingPoint[1] - normVec[2] * rayStartingPoint[2]) /
(normVec[0] * rayDirection[0] + normVec[1] * rayDirection[1] + normVec[2] * rayDirection[2]);
glm::vec3 crosspoint = rayStartingPoint + rayDirection * glm::vec3(directionMultiplikator);
if (glm::dot(crosspoint - helperVec,normVec) == 0) {
float x = glm::dot(directionVecA,crosspoint - helperVec);
float y = glm::dot(directionVecB, crosspoint - helperVec);
if (x > -0.5001 && x < 0.5001) {
if (y > -0.5001 && y < 0.5001) {
return true;
}
}   
}
}
return false;
}

编辑:我修改了我的代码,现在点击立方体在很多情况下被检测到。

我想是时候回答我自己的问题了。我的代码的实际问题是检查glm::dot(crosspoint - helperVec,normVec) == 0。但相反,我应该检查glm::abs(glm::dot(crosspoint - helperVec,normVec)) < EPSILON与一个非常小的EPSILON值。

注意:当使用浮点数时,永远不要检查0

相关内容

  • 没有找到相关文章

最新更新