C++ Rubiks Cube - 检查射线和立方体相交的问题

问题描述 投票:0回答:0

我现在被我的 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,但没什么用。

我只是无法正确实施它。

c++ intersection glm-math rubiks-cube
© www.soinside.com 2019 - 2024. All rights reserved.