如何检测三角形与矩形的点击事件?附椭圆点击检测参考代码
三角形与矩形的点击检测实现方案
嘿,看你已经搞定了椭圆的点击检测,那咱们直接来实现三角形和矩形的版本!下面是针对这两种形状的onClickEvent方法实现,和你现有的椭圆逻辑风格保持一致,也考虑了缩放变换的影响~
一、矩形的点击检测
矩形的点击判断逻辑很直观:只要点击点落在经过缩放后的矩形边界范围内就算命中。我们需要先计算出矩形实际的左上角、右下角坐标,再判断点击点的x、y是否在这个区间里。
@Override protected void onClickEvent(float x, float y) { // 获取矩形缩放后的实际宽高 float actualWidth = getWidth() * getScaleX(); float actualHeight = getHeight() * getScaleY(); // 取矩形的中心坐标(假设你的形状类有getX()、getY()方法获取中心位置) float centerX = getX(); float centerY = getY(); // 计算矩形的四个边界 float left = centerX - actualWidth / 2; float right = centerX + actualWidth / 2; float top = centerY - actualHeight / 2; float bottom = centerY + actualHeight / 2; // 判断点击点是否在矩形内部 boolean isClicked = (x >= left && x <= right) && (y >= top && y <= bottom); if (isClicked) { // 这里写点击后的触发逻辑,比如选中状态切换、回调通知等 handleClick(); } }
二、三角形的点击检测
三角形的点击判断常用叉乘法:通过计算点击点与三角形三条边的叉积,判断点是否在三条边的同一侧(根据三角形的顺时针/逆时针绘制方向)。如果三个叉积的符号一致(全正或全负),说明点在三角形内部。
首先假设你的Triangle类存储了三个顶点的原始坐标,或者有方法可以获取经过缩放、平移后的实际顶点位置:
@Override protected void onClickEvent(float x, float y) { // 获取三角形经过缩放、平移后的三个实际顶点坐标 PointF v1 = getTransformedVertex1(); // 需实现:返回应用了scale和translate后的顶点 PointF v2 = getTransformedVertex2(); PointF v3 = getTransformedVertex3(); // 计算三个边与点击点的叉积 float cross1 = crossProduct(v2.x - v1.x, v2.y - v1.y, x - v1.x, y - v1.y); float cross2 = crossProduct(v3.x - v2.x, v3.y - v2.y, x - v2.x, y - v2.y); float cross3 = crossProduct(v1.x - v3.x, v1.y - v3.y, x - v3.x, y - v3.y); // 处理浮点精度误差,用小阈值判断正负 boolean hasNegative = (cross1 < -0.001f) || (cross2 < -0.001f) || (cross3 < -0.001f); boolean hasPositive = (cross1 > 0.001f) || (cross2 > 0.001f) || (cross3 > 0.001f); // 只有当三个叉积符号一致时,点在三角形内部 boolean isClicked = !(hasNegative && hasPositive); if (isClicked) { // 点击触发逻辑 handleClick(); } } // 辅助方法:计算二维向量的叉积 private float crossProduct(float ax, float ay, float bx, float by) { return ax * by - ay * bx; }
补充说明
- 三角形的
getTransformedVertex方法需要把原始顶点坐标应用缩放和平移变换,示例实现如下:private PointF getTransformedVertex1() { PointF original = getVertex1(); // 获取原始顶点坐标 return new PointF( getX() + original.x * getScaleX(), getY() + original.y * getScaleY() ); } - 浮点精度阈值(0.001f)可以根据你的业务需求调整,避免因计算误差导致的误判。
内容的提问来源于stack exchange,提问作者Emas
相关产品推荐
相关产品推荐

