所以从这里的这个问题开始:圆形按钮,我想我需要创建一种视图边缘的地图,假设我有一个看起来像这样的视图:
该按钮不会是蓝色或任何特定颜色,因此我们无法检查用户触摸的位置是否为蓝色,这是上一个问题中的一个答案所建议的。
假设我收到了一个触摸事件,我在这个视图中得到了触摸的位置,视图是矩形的,我只想在他们按下蓝色部分时接受输入。我怎么能弄清楚这个?
让我们假设图形的边界框完全填满了视图。我们可以如下进行。感兴趣的区域以两个同心圆和视图为界。(圆心是视图的右下角。)当我们得到触摸时,我们只需要计算从触摸坐标到右下角的距离,并将其与两个圆半径进行比较。(您可以通过将平方距离与平方半径进行比较来避免平方根。)如果距离在半径之间,则触摸为蓝色(或任何颜色)。我们不需要计算触摸是否在边界框内;我们已经知道,因为事件被传递到视图。
这是一些示例代码。它用于确定一个点是否在两个同心圆(一个环形)内的检测器,如果是,它会击中哪个象限。
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;
}
}
}
我建议创建代表该形状的顶部和底部曲线的方程,2 个倒置抛物线,并检查y 在给定 x 值处是否大于底部曲线方程的 y,并且 y小于给定 x 值处的顶部曲线的 y(并且 y 大于 0,假设 0 是底部,并且 x 小于按钮的右侧多远)。