我现在被我的 RubiksCube 项目困住了。
我想要实现的目标:左键单击检查是否单击了多维数据集。 (点击时立方体可能会旋转)
其他魔方类的代码工作正常(由教授提供)。 我认为问题是因为缺少一些坐标系转换但我真的很无能,尝试了很多东西但没有解决:(。 我们需要自己用数学公式计算函数。
我的总体想法是保护每一层的 4 个角点的坐标。 这些将用于计算
void MergedCube::Render(float aspectRatio)
{
// mat4_cast transforms Quaternion in corresponding Rotation matrix
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);
// Offset between the Cubies central Points
float offset = m_cubieRenderer.GetCubieExtension() + 0.05f;
// Iterating over the 27 Mini Cubies
for (int i = 0; i < 3; ++i)
{
for (int j = 0; j < 3; ++j)
{
for (int k = 0; k < 3; ++k)
{
// Local transformation
glm::vec3 localPoint = (glm::vec3(i, j, k) - 1.0f) * offset;
// First local transformation then global transformation
compound = glm::translate(m_viewProject, localPoint);
glm::vec4 translatedVertice = compound * glm::vec4(testVec,1.0);
// Adding Corner Points
// pushback(translatedVertice) for corresponding Layer
m_cubieRenderer.Render(compound);
}
}
}
// Calculations for every Layer
NormalVectors(leftLayer, 1);
NormalVectors(rightLayer, -1);
NormalVectors(lowerLayer, 1);
NormalVectors(upperLayer, -1);
NormalVectors(frontLayer, 1);
NormalVectors(backLayer, -1);
}
现在数学部分开始了。 这个方法应该计算我的辅助向量,2个方向向量 和每一层的归一化向量
void MergedCube::NormalVectors(std::vector<glm::vec3>& points, int normDirection) {
while (points.size() > 4) {
points.erase(points.begin());
}
// calculating the middle Point of every Layer
// Adding up the 2 opposite corner points and dividing :2
float midX = (points[0][0] + points[3][0]) / 2.0f;
float midY = (points[0][1] + points[3][1]) / 2.0f;
float midZ = (points[0][2] + points[3][2]) / 2.0f;
glm::vec3 middlePoint = glm::vec3(midX,midY,midZ);
// thought these could be somehow useful in the future, gonna see later
float firstPointX = (points[0][0] + points[1][0]) / 2.0f;
float firstPointY = (points[0][1] + points[1][1]) / 2.0f;
float firstPointZ = (points[0][2] + points[1][2]) / 2.0f;
glm::vec3 firstPoint = glm::vec3(firstPointX, firstPointY, firstPointZ);
float secondPointX = (points[0][0] + points[2][0]) / 2.0f;
float secondPointY = (points[0][1] + points[2][1]) / 2.0f;
float secondPointZ = (points[0][2] + points[2][2]) / 2.0f;
glm::vec3 secondPoint = glm::vec3(secondPointX, secondPointY, secondPointZ);
// calculating the 2 direction vectors and normalizing
glm::vec3 vecA = firstPoint - middlePoint;
glm::vec3 vecB = secondPoint - middlePoint;
vecA = glm::normalize(firstPoint - middlePoint);
vecB = glm::normalize(secondPoint - middlePoint);
// calculating normalized normalisatiion vector
glm::vec3 normalVector = glm::cross(vecA,vecB);
// the 2 opposite layer´s normalisation vectors move in opposite directions
normalVector[0] = normalVector[0] * normDirection;
normalVector[1] = normalVector[1] * normDirection;
normalVector[2] = normalVector[2] * normDirection;
points.push_back(firstPoint);
points.push_back(secondPoint);
points.push_back(middlePoint);
points.push_back(vecA);
points.push_back(vecB);
points.push_back(normalVector);
while (points.size() > 6) {
points.erase(points.begin());
}
}
最后最糟糕的部分是 RayAndCubeIntersection 方法。
bool MergedCube::RayAndCubeIntersection(glm::vec3 startingPoint, glm::vec3 direction,
std::vector<glm::vec3> Pts) {
// Checking if ray and normalisation vector have the same direction
if (glm::dot(direction, Pts[5]) < 0) {
// Using hese normal form to calculate crosspoint
float res = Pts[5][0] * Pts[2][0] + Pts[5][1] * Pts[2][1] + Pts[5][2] * Pts[2][2];
float directionMultiplikator = (res - Pts[5][0] * startingPoint[0] -
Pts[5][1] * startingPoint[1] -
Pts[5][2] * startingPoint[2]) /
(Pts[5][0] * direction[0] +
Pts[5][1] * direction[1] +
Pts[5][2] * direction[2]);
glm::vec3 crosspoint = glm::vec3((startingPoint[0] +
directionMultiplikator * direction[0]),
(startingPoint[1] + directionMultiplikator * direction[1]),
(startingPoint[2] + directionMultiplikator * direction[2]));
// Enter if crosspoint is on layer
if (glm::dot(Pts[5], crosspoint - Pts[2]) == 0) {
float x = glm::dot(Pts[3],crosspoint - Pts[2]);
float y = glm::dot(Pts[4], crosspoint - Pts[2]);
// Professor gave us this code, every Cubie is 1.0f long
// so with offset it should be [-1.5001,1.5001]
if (x > -1.5501 && x < 1.5501) {
if (y > -1.5501 && y < 1.5501) {
return true;
}
}
}
}
return false;
}
我真的很感激每一个关于在哪里可以找到可能的问题的提示!
我尝试改变Ray点和方向的坐标系 到局部坐标系,但它导致该点最终出现在不同的宇宙中 z = -130.
然后我尝试在这两个上使用我的转换矩阵。 我试图保护图层中的局部角点。
好吧,我试着问了 chatGPT,但没什么用。
我只是无法正确实施它。