2

如果您触摸这种等距onTouchEvent形状的不规则形状,我该如何办理登机手续?

希望您能够帮助我。

4

4 回答 4

1

检查MotionEvent坐标是否在您的形状内,然后进行多边形点命中测试。

如果您的等距形状是具有等长段的钻石,并且所有角度均为 90 度(由 Geobits 在评论中更正),则可以使用Manhatten Distance进行快速测试。查看链接,图片更清楚地说明了它的工作原理。

int rectSize = 10;
Rectangle diamondBoundingRect = new Rectangle(0,0,rectSize,rectSize);
Point point = new Point(9,9);
int dx = Math.abs(point.x - diamondBoundingRect.center.x);
int dy = Math.abs(point.y - diamondBoundingRect.center.y);
if(dx+dy < rectSize){
    //point is inside diamond
}else{
    //point is not inside diamond
}

这个测试不灵活,但它可能就是你所需要的。

如果您需要更好的东西,这篇博文解释了多边形点命中测试的算法。

这个想法是从您的MotionEvent点投射一条线(称为射线)到您的多边形,并计算该线与该多边形中线段之间的交叉点数。如果计数是偶数,则该点在形状之外。如果它很奇怪,则该点位于形状内部。

维基百科有一张漂亮的图片和更多的细节来帮助你理解这种方法的逻辑。

在下一部分之前集中精力让它发挥作用,因为根据您的需要,这可能证明是不必要的。

在您的发送给您的积分onTouchEvent被采样。该设备只是以预定的速率为您提供点和方向。用户移动手指的速度越快,您拥有的细节就越少,因为采样率跟不上。

所以,如果你想要更多细节,你将不得不插值。这是一种高级的说法,你需要用一些花哨的数学来猜测用户在哪里滑动手指。过去,余弦插值对我来说效果很好,因为它在速度和结果之间取得了很好的平衡。

编辑:

这是我个人用于多边形点命中测试的一些代码。

public boolean isPointInsidePolygon(double x, double y){
    //pointAry holds the polygon's vertices.
    int polySides = this.pointAry.Length;
    //need at lest 3 vertices to create a polygon.
    if (polySides < 3)
    {
        return false;
    }
    int j = polySides - 1;
    boolean oddNodes = false;
    for (int i = 0; i < polySides; i++)
    {
        Point pi = this.pointAry[i];
        Point pj = this.pointAry[j];
        if (pi.y < y && pj.y >= y || pj.y < y && pi.y >= y)
        {
            if (pi.x + (y - pi.y) / (pj.y - pi.y) * (pj.x - pi.x) < x)
           {
                oddNodes = !oddNodes;
            }
        }
        j = i;
     }
     return oddNodes;
 }
于 2013-07-31T14:10:25.677 回答
1

检查坐标MotionEvent是否在您的形状内:

@Override
public boolean onTouchEvent(MotionEvent event)
{
    final float x = event.getX();
    final float y = event.getY();
    if (isInside(x, y))
    {
         // do something
    }
    return true;
}

boolean isInside(float x, float y)
{
    // TODO: return true, if (x,y) is inside your shape, otherwise return false
}
于 2013-07-31T14:04:01.143 回答
0

如果您在 SurfaceView 上将形状绘制为位图,则只需测试您触摸的像素的透明度。Bitmap 的像素,即不是 SurfaceView 的。

例如,在 100,150 处绘制位图(左/上的表面视图坐标):

float x = getX() - 100;
float y = getY() - 150;
int alpha = Color.alpha(myBitmap.getPixel(x, y));
if(alpha == 0)
    // not hit!
else
    // hit!

注意:这不会使缩放生效,因此如果要按比例绘制它们,则必须知道比例因子并相应地相乘。

于 2013-07-31T20:14:23.533 回答
0

您可以编写一些代码来检测给定点 (x, y) 是否在您的不规则形状中。

public boolean isInIrregularShape(int x, int y);

您必须以某种方式定义形状。您可能想在 Google 上搜索一些库,这些库可让您定义形状并检查给定点是否在形状内。您的 x 和 y 点将是event.getX()and event.getY()

于 2013-07-31T14:26:19.617 回答