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

在Visual Studio 2017与OpenFrameworks中判断变换后三角形的鼠标命中

问题根源

ofPushMatrix()/ofPopMatrix()仅作用于绘制管线的坐标转换,不会修改你用来定义三角形的原始顶点数据。insideTriangleArea()用的是未做任何变换的原始顶点,去匹配屏幕坐标系下的鼠标位置,自然无法对应上平移、旋转、缩放后的绘制区域——相当于你在局部坐标系里定义了三角形,却直接拿屏幕坐标去做碰撞检测,两者不在同一坐标系下。

解决方法

有两种可行的思路,核心都是让鼠标点和三角形顶点处于同一坐标系:

思路1:将鼠标坐标逆变换到三角形的局部坐标系

把屏幕鼠标点通过与绘制时相反的变换,转换到三角形未做任何变换前的局部坐标系,再用这个转换后的点去调用检测函数:

// 1. 定义原始三角形顶点(示例为以原点为中心的局部坐标)
vector<ofVec2f> triangleVerts = {
    ofVec2f(-50, -50),
    ofVec2f(50, -50),
    ofVec2f(0, 50)
};

// 2. 绘制时的变换参数
ofVec2f fPT = ofVec2f(400, 300);
float fRotate = 45.0f;
float fScale = 1.5f;

// 3. 构建绘制时的变换矩阵并求逆
ofMatrix4x4 transformMatrix;
transformMatrix.translate(fPT);
transformMatrix.rotateDeg(fRotate, 0, 0, 1); // 2D旋转绕Z轴
transformMatrix.scale(fScale, fScale, 1.0f);
ofMatrix4x4 inverseMatrix = transformMatrix.getInverse();

// 4. 获取鼠标屏幕坐标并转换到局部坐标系
ofVec2f mouseScreen(ofGetMouseX(), ofGetMouseY());
ofVec3f mouseLocal = inverseMatrix * ofVec3f(mouseScreen.x, mouseScreen.y, 0.0f);
ofVec2f mouseLocal2D(mouseLocal.x, mouseLocal.y);

// 5. 执行碰撞检测
bool isInside = insideTriangleArea(triangleVerts[0], triangleVerts[1], triangleVerts[2], mouseLocal2D);

思路2:提前计算变换后的三角形顶点

先把原始顶点通过变换矩阵转换为屏幕坐标系下的顶点,再直接用鼠标屏幕坐标做检测:

// 1. 原始顶点与变换参数同上
vector<ofVec2f> triangleVerts = { /* ... */ };
ofVec2f fPT = { /* ... */ };
float fRotate = /* ... */;
float fScale = /* ... */;

// 2. 构建变换矩阵
ofMatrix4x4 transformMatrix;
transformMatrix.translate(fPT);
transformMatrix.rotateDeg(fRotate, 0, 0, 1);
transformMatrix.scale(fScale, fScale, 1.0f);

// 3. 计算变换后的屏幕坐标顶点
ofVec2f vertScreen0 = transformMatrix * triangleVerts[0];
ofVec2f vertScreen1 = transformMatrix * triangleVerts[1];
ofVec2f vertScreen2 = transformMatrix * triangleVerts[2];

// 4. 用屏幕坐标直接检测
ofVec2f mouseScreen(ofGetMouseX(), ofGetMouseY());
bool isInside = insideTriangleArea(vertScreen0, vertScreen1, vertScreen2, mouseScreen);
关键注意点
  • 不要依赖ofPushMatrix()的作用域来影响碰撞检测——这个函数只是给绘制阶段的OpenGL上下文设置矩阵,不会改变你的顶点数据或鼠标坐标的坐标系。
  • 两种思路的本质都是坐标系对齐:要么把鼠标转到局部坐标系,要么把顶点转到屏幕坐标系,必须保证检测时两者处于同一坐标系。

内容的提问来源于stack exchange,提问作者James C Wright

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 20:32:44