英文:
Problem on checking Ray and Cube intersection
问题
以下是您要翻译的部分:
I am stuck right now with my RubiksCube Project.
What I want to achieve: On left-click checking if a single Mini-Cubie was clicked or not.
(The Cube might be rotated when clicked)
The Code of the other Rubiks Cube classes works correctly.
We need to calculate the functions on our own with math formulas.
Current Problems:
- Clicking on Edges is not being detected
- After the rotation clicking at a point sometimes leads to: Wrong layer being marked as clicked or no layer being marked as clicked
My general idea was to save the coords of every Layer's 4 Corner Points, updating their position when rotated and checking the Intersection of the Ray with help of these locations
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
}
This method is supposed to calculate my helper vector, the 2 direction vectors
and the normalization vector of every Layer
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.add(vecB);
points.push_back(normalVector);
}
Now the RayAndCubeIntersection method.
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 directionMultiplier = (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(directionMultiplier);
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;
}
Edit: I changed my Code quite a bit, now clicking the cube is being detected in many cases.
英文:
I am stuck right now with my RubiksCube Project.
What I want to achieve: On left-click checking if a single Mini-Cubie was clicked or not.
(The Cube might be rotated when clicked)
The Code of the other Rubiks Cube classes works correctly.
We need to calculate the functions on our own with math formulas.
Current Problems:
- Clicking on Edges is not being detected
- After the rotation clicking at a point sometimes leads to: Wrong layer being marked as clicked or no layer being marked as clicked
My general idea was to safe the coords of every Layer´s 4 Corner Points, updating their position when rotated and checking the Intersection of the Ray with help of these locations
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
}
This method is supposed to calculate my helper vector, the 2 direction vectors
and the normalisation vector of every Layer
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);
}
Now the RayAndCubeIntersection method.
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;
}
Edit: I changed my Code quite a bit, now clicking the cube is being detected in many cases.
答案1
得分: 0
以下是您要翻译的内容:
原文:
Well I guess it is time to answer my own question.
The actual problem of my code was checking glm::dot(crosspoint - helperVec,normVec) == 0
.
But instead I am supposed to check for glm::abs(glm::dot(crosspoint - helperVec,normVec)) < EPSILON
with a really small EPSILON value.
Note to myself: When using floats never check against 0
翻译:
好吧,我想是时候回答自己的问题了。
我的代码实际问题是检查 glm::dot(crosspoint - helperVec,normVec) == 0
。
而实际上,我应该检查 glm::abs(glm::dot(crosspoint - helperVec,normVec)) < EPSILON
,EPSILON 值应该非常小。
自己提醒:在使用浮点数时,永远不要检查是否等于 0。
英文:
Well I guess it is time to answer my own question.
The actual problem of my code was checking glm::dot(crosspoint - helperVec,normVec) == 0
.
But instead I am supposed to check for glm::abs(glm::dot(crosspoint - helperVec,normVec)) < EPSILON
with a really small EPSILON value.
Note to myself: When using floats never check against 0
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论