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

如何检测三角形与矩形的点击事件?附椭圆点击检测参考代码

三角形与矩形的点击检测实现方案

嘿,看你已经搞定了椭圆的点击检测,那咱们直接来实现三角形和矩形的版本!下面是针对这两种形状的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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 08:47:12