创建按钮边缘的“地图”

Posted

技术标签:

【中文标题】创建按钮边缘的“地图”【英文标题】:Creating a "map" of the edges of a button 【发布时间】:2012-09-04 21:16:16 【问题描述】:

所以从这里的这个问题开始:Rounded buttons,我想我需要创建一种视图边缘的地图,假设我有一个看起来像这样的视图:

按钮不会是蓝色或任何特定颜色,因此我们无法检查用户触摸的位置是否为蓝色,这是上一个问题中的一个答案所建议的。

假设我收到了一个触摸事件,我在这个视图中获得了触摸的位置,视图是矩形的,我只想在他们按下蓝色部分时接受输入。我怎么能弄清楚这个?

【问题讨论】:

【参考方案1】:

让我们假设图形的边界框正好填满了视图。我们可以如下进行。感兴趣的区域以两个同心圆和视图为界。 (圆心是视图的右下角。)当我们得到触摸时,我们只需要计算从触摸坐标到右下角的距离,并将其与两个圆半径进行比较。 (您可以通过将平方距离与平方半径进行比较来避免平方根。)如果距离在半径之间,则触摸为蓝色(或任何颜色)。我们不需要计算触摸是否在边界框内;我们已经知道,因为事件被传递到视图。

这里有一些示例代码。它用于检测器确定一个点是否在两个同心圆(一个环形)内,如果是,它会击中哪个象限。

public class ArcHitDetector 
    public enum Quadrant 
        TOP_LEFT, TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT
    
    private int xCenter, yCenter, innerR2, outerR2;
    /**
     * Construct an ArcHitDetector for an annulus centered at given
     * points and with given inner and outer radii.
     *
     * @param xCenter the horizontal center coordinate
     * @param yCenter the vertical center coordinate
     * @param outerR the outer radius of the annulus
     * @param innerR the inner radius of the annulus
     */
    public ArcHitDetector(int xCenter, int yCenter, int outerR, int innerR) 
        this.xCenter = xCenter;
        this.yCenter = yCenter;
        this.outerR2 = outerR * outerR;
        this.innerR2 = innerR * innerR;
    

    /**
     * Classify a point with respect to the annulus. It assumes
     * screen coordinates (x increases to the right; y increases
     * down).
     *
     * @param x the x coordinate of the point to test
     * @param y the y coordinate of the point to test
     *
     * @return the Quadrant of the annulus in which the point falls,
     *    or null if the point does not lie in the annulus
     */
    public Quadrant classifyHit(int x, int y) 
        int dx = x - xCenter;
        int dy = y - yCenter;
        int d2 = dx * dx + dy * dy;
        if (d2 <= outerR2 && d2 >= innerR2) 
            if (x >= xCenter) 
                return y <= yCenter ? TOP_RIGHT : BOTTOM_RIGHT;
             else 
                return y <= yCenter ? TOP_LEFT : BOTTOM_LEFT;
            
         else 
            return null;
        
    

【讨论】:

我们有一些代码来生成这个吗?假设弧线是“完美的”,但如果不是呢? @SmartLemon - 我添加了一些示例代码。一般来说,不完美的弧线并不是什么大问题。只需在计算中添加一点斜率(例如,增加外半径并减少内半径)。无论如何,触摸事件并不是那么准确。如果曲线与圆显着不同(例如,它们是椭圆),请相应地更改方程。 嗯,谢谢,我会整理一下,谢谢你的帮助。【参考方案2】:

我建议创建代表该形状的顶部和底部曲线的方程,2 个倒置抛物线,并检查 y 是否大于给定底部曲线的 y 方程x 值,并且在给定的 x 值处,y 小于顶部曲线的 y(并且 y 大于 0,假设 0 是底部,但是 x 小于你的按钮在最右边)。

【讨论】:

以上是关于创建按钮边缘的“地图”的主要内容,如果未能解决你的问题,请参考以下文章

Tailwindcss 下拉项目飞到屏幕边缘而不是下拉按钮下方

Android中百度地图如何重新获取坐标

搞清游戏迭代的周期律 就能找到产业地图创新边缘

如何在按钮边缘上制作cornerRadius,以便在swiftUI中不剪裁边缘

自定义 UIButton 的边缘在与它交互后看起来像素化

游戏开发实战2D游戏摄像机镜头跟随,屏幕边缘限制镜头移动(使用Cinemachine组件)