Android:如何检查路径是否包含触摸点?

kin*_*mer 18 android contains path drawable android-canvas

我会尝试开发一个可以绘制平面测量的应用程序.因此,每个房间都有自己的ID名称,如果我触摸房间,我想显示带有该ID或名称的Toast消息.问题是如何检查是否以及触及了哪条路径!!

我看到很多讨论这个问题的主题讨论.有人说使用getBounds方法,之后包含检查触摸点是否在Rect中的方法.但是,我猜getBounds方法返回包含路径的最小Rect,对吧?

因此,房间有不同的自定义几何形式,因此,如果我约束了2个关闭房间,方法可以返回一组共享点.坏!每个房间只有他们的面积点.我怎么解决这个问题 ?

在iOS中我可以使用PathContainsPoint方法,但不幸的是,Android Path没有类似的东西.

我希望有人可以提前帮助我

kin*_*mer 42

好的,我解决了我的问题.我发布了示例代码:

Path p;
Region r;

@Override
public void onDraw(Canvas canvas) {

    p = new Path();

    p.moveTo(50, 50);
    p.lineTo(100, 50);
    p.lineTo(100, 100);
    p.lineTo(80, 100);
    p.close();      

    canvas.drawPath(p, paint);

    RectF rectF = new RectF();
    p.computeBounds(rectF, true);
    r = new Region();
    r.setPath(p, new Region((int) rectF.left, (int) rectF.top, (int) rectF.right, (int) rectF.bottom));

}   

public boolean onTouch(View view, MotionEvent event) {

    Point point = new Point();
    point.x = event.getX();
    point.y = event.getY();
    points.add(point);
    invalidate();
    Log.d(TAG, "point: " + point);

    if(r.contains((int)point.x,(int) point.y))
        Log.d(TAG, "Touch IN");
    else
        Log.d(TAG, "Touch OUT");

    return true;
}
Run Code Online (Sandbox Code Playgroud)

  • 这标识了路径周围给定边界多边形而不是折线上的触摸事件. (2认同)
  • 仅供参考,在onDraw中创建新的RectF和Region不利于性能,如果可能的话,可以更好地重用。 (2认同)

Nik*_*ita 8

正如 Edward Falk 所说,最好的方法是使用path.op() 因为Region 是方形的。并且一个点可以在 2 或 3 个区域。

例如:

在此处输入图片说明

所有区域都将包含蓝点,但实际上只有 path4 包含该点。

int x, y;
Path tempPath = new Path(); // Create temp Path
tempPath.moveTo(x,y); // Move cursor to point
RectF rectangle = new RectF(x-1, y-1, x+1, y+1); // create rectangle with size 2xp
tempPath.addRect(rectangle, Path.Direction.CW); // add rect to temp path
tempPath.op(pathToDetect, Path.Op.DIFFERENCE); // get difference with our PathToCheck
if (tempPath.isEmpty()) // if out path cover temp path we get empty path in result
{ 
    Log.d(TAG, "Path contains this point");
    return true;
}
else
{
    Log.d(TAG, "Path don't contains this point");
    return false;
}
Run Code Online (Sandbox Code Playgroud)