opengl中如何确定鼠标的点击坐标在一个圆柱体范围之内?

在OpenGL中确定鼠标点击坐标在圆柱体范围内的方法有多种。一种常用的方法是使用投影和反投影矩阵。首先,你需要在渲染圆柱体之前设置投影矩阵,然后在鼠标点击事件中获取当前点击坐标。接下来,使用反投影矩阵将当前点击坐标转换为世界坐标。最后,计算当前点击坐标与圆柱体中心点之间的距离(只看x,y),并判断该距离是否小于圆柱体的半径,还需要在计算距离时考虑圆柱体的高度(只看z)。可以使用如下代码来判断点击坐标是否在圆柱体范围内:

普通算法

void onMouseClick(int x, int y) {
    // 获取当前点击坐标
    glm::vec4 viewport = glm::vec4(0, 0, window_width, window_height);
    glm::vec3 wincoord = glm::vec3(x, y, 0);
    glm::vec3 objcoord = glm::unProject(wincoord, view * model, projection, viewport);

    // 计算点击坐标与圆柱体中心点之间的距离
    float dx = objcoord.x - cylinder_center.x;
    float dy = objcoord.y - cylinder_center.y;
    float distance = sqrt(dx * dx + dy * dy);
    
    // 判断距离是否小于圆柱体半径
    if (distance < cylinder_radius) {
        // 判断高度是否在圆柱体高度范围内
        float cylinder_height = cylinder_top - cylinder_bottom;
        if (objcoord.z > cylinder_bottom && objcoord.z < cylinder_top) {
            // 点击坐标在圆柱体范围内
            std::cout << "Click inside cylinder" << std::endl;
        } else {
            std::cout << "Click outside cylinder" << std::endl;
        }
    } else {
        std::cout << "Click outside cylinder" << std::endl;
    }
}

需要注意的是,这里假定你已经知道了圆柱体的中心,半径,高度的顶部和底部,还有投影矩阵和视图矩阵。

用点到直线的距离来判断

对于圆柱体来说,应该用点到直线的距离来判断点是否在圆柱体范围内。
下面是一个示例代码,用来判断点击坐标是否在圆柱体范围内:

void onMouseClick(int x, int y) {
    // 获取当前点击坐标
    glm::vec4 viewport = glm::vec4(0, 0, window_width, window_height);
    glm::vec3 wincoord = glm::vec3(x, y, 0);
    glm::vec3 objcoord = glm::unProject(wincoord, view * model, projection, viewport);

    // 定义圆柱体的顶点和底点
    glm::vec3 top_vertex = glm::vec3(cylinder_center.x, cylinder_center.y, cylinder_top);
    glm::vec3 bottom_vertex = glm::vec3(cylinder_center.x, cylinder_center.y, cylinder_bottom);

    // 计算点击坐标到圆柱体轴线的距离
    glm::vec3 v = objcoord - bottom_vertex;
    glm::vec3 u = top_vertex - bottom_vertex;//轴线向量
    float d = glm::length(glm::cross(v, u)) / glm::length(u);

    // 判断距离是否小于圆柱体半径
    if (d <= cylinder_radius) {
        // 判断点是否在高度范围内
        if (objcoord.z > cylinder_bottom && objcoord.z < cylinder_top) {
            // 点击坐标在圆柱体范围内
            std::cout << "Click inside cylinder" << std::endl;
        } else {
            std::cout << "Click outside cylinder" << std::endl;
        }
    } else {
        std::cout << "Click outside cylinder" << std::endl;
    }
}

补充:点到直线距离计算公式1

需要注意的是,这里假定你已经知道了圆柱体的中心,半径,高度的顶部和底部,还有投影矩阵和视图矩阵。

还有,这段代码中的变量,需要您在调用之前预先定义和初始化,比如圆柱体的半径,中心,高度等。

此外,点击事件的处理可能因平台和框架而异,所以在实际应用中需要根据具体情况进行调整。

进一步完善

事实上,上面描述的是垂直放置的圆柱体,因此圆柱体高度的顶部和底部是确定的,但若是倾斜的圆柱体,需要知道顶部面和底部面的公式,随后用点到面的距离判断是否在范围内。
如果圆柱体是倾斜的,则需要知道顶部面和底部面的方程。点到面的距离可以使用点积运算来计算。您可以使用平面的法向量和一个点来描述平面。在求点到面的距离时,只需要把点代入平面方程来计算即可。

1.点到面的距离公式

例如:给定圆柱体顶面方程ax + by + cz + d = 0,点(x0,y0,z0)到圆柱体顶面的距离为:

distance = abs(ax0 + by0 + cz0 + d) / sqrt(aa + bb + cc)

2.平面方程计算方法

可以通过已知的圆柱体顶面中心点和底面中心点来求出顶面和底面的法向量,再通过点乘法来计算出平面方程。这样就可以用点到平面的距离来判断点是否在圆柱体范围内了。
具体的实现方式如下:

  • 求出圆柱体顶面法向量: top_normal = normalize(top_center - bottom_center)
  • 求出点到顶面的距离: distance = dot(top_normal, objcoord - top_center)

如果需要求出底面的距离,只需要把top_center换成bottom_center就可以了

需要注意的是,这里假设你已经知道了圆柱体的顶部和底部的中心点,还有投影矩阵和视图矩阵。


  1. opengl中如何确定鼠标的点击坐标在一个圆柱体范围之内?_第1张图片 ↩︎

你可能感兴趣的:(OpenGL,高等数学,c++,开发语言)