You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

魔方项目:射线与小魔方块交点检测功能故障求助

魔方点击检测功能实现瓶颈求助

我正在开发魔方(RubiksCube)项目,目前卡在左键点击检测单个小魔方块(Mini-Cubie)的功能上——魔方处于旋转状态时也需要正常完成检测。项目中其他魔方相关类的代码运行正常,我需要通过数学公式自行实现该检测功能。

当前存在的问题

  • 点击魔方边缘时无法被检测到;
  • 魔方旋转后点击,偶尔会出现标记错误图层或无图层被标记的情况。

实现思路

我计划保存每个图层的4个角点坐标,在魔方旋转时更新这些坐标,再借助这些位置信息检测射线与方块的交点。相关代码如下:

Render方法

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


}

LayerCalculation方法

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;
}

编辑说明:我已经对代码做了不少修改,现在多数情况下点击魔方可以被检测到,但上述两个问题仍然存在。

内容的提问来源于stack exchange,提问作者Diazodiac

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 11:45:02