Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/223.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android:如何检查路径是否包含接触点?_Android_Path_Drawable_Contains_Android Canvas - Fatal编程技术网

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

Android:如何检查路径是否包含接触点?,android,path,drawable,contains,android-canvas,Android,Path,Drawable,Contains,Android Canvas,我会尝试开发一个应用程序,在其中我可以画一个平面图。因此,每个房间都有自己的ID或名称,如果我触摸一个房间,我想用该ID或名称显示祝酒词。问题是如何检查是否接触以及接触的路径 我看到很多关于这个问题的专题讨论。有人说要使用getBounds方法,然后包含检查接触点是否在Rect中的方法。但是,我猜getBounds返回包含路径的最小Rect,对吗 所以,房间有不同的自定义几何形式,出于这个原因,若我得到两个封闭房间的边界,该方法可以返回一组共享的点。糟糕!每个房间只有它们的面积点。我怎样才能解决

我会尝试开发一个应用程序,在其中我可以画一个平面图。因此,每个房间都有自己的ID或名称,如果我触摸一个房间,我想用该ID或名称显示祝酒词。问题是如何检查是否接触以及接触的路径

我看到很多关于这个问题的专题讨论。有人说要使用
getBounds
方法,然后包含检查接触点是否在Rect中的方法。但是,我猜
getBounds
返回包含路径的最小
Rect
,对吗

所以,房间有不同的自定义几何形式,出于这个原因,若我得到两个封闭房间的边界,该方法可以返回一组共享的点。糟糕!每个房间只有它们的面积点。我怎样才能解决这个问题


在iOS中,我可以使用
PathContainsPoint
方法,但不幸的是,Android Path没有类似的功能。

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

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;
}

这里有一个想法:创建一条新的路径,它是一个围绕被接触点的小正方形,然后将该路径与要使用的路径相交,看看结果是否为空。

正如Edward Falk所说,最好的方法是使用,因为区域是正方形的。一个点可以在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;
}
Region和path.op()方法工作正常,但缺乏精确性。在一些测试之后,它们似乎在路径的段级别定义了一个区域,如下所示:。另一种方法是与客户合作。虽然效果更好,但它仍然记录了一些意想不到的触动,并忽略了明显的触动。但还有另一种解决方案,它包括沿着路径检索一组点,并在它们周围的区域内注册触摸。为此,我们可以使用
PathMeasure
类获得所需的点数,并将它们存储在
列表中

PathMeasure-PathMeasure=新的PathMeasure(路径,false);
List listFloat=new ArrayList();
对于(浮动i=0;i<1.1;i+=0.1){
浮点[]点坐标=新浮点[2];
getPosTan(pathMeasure.getLength()*i,点坐标,null);
添加(点坐标[0]);
添加(点坐标[1]);
}
然后,我们需要循环查看
列表
,并检查触摸事件是否位于围绕这些点的定义区域内。这里,一个区域覆盖了路径长度的十分之一,因为我们收集了十个点:

float areaLength = pathMeasure.getLength() / 20; // since we collect ten points, we define a zone covering a tenth of path length    
for (int i = 0; i < listFloat.size() - 1; i += 2) {
    if (touchX > listFloat.get(i) - areaLength
     && touchX < listFloat.get(i) + areaLength
     && touchY > listFloat.get(i+1) - areaLength
     && touchY < listFloat.get(i+1) + areaLength) {
        Log.d(TAG, "path touched");
    }

}
float areaLength=pathMeasure.getLength()/20;//因为我们收集了10个点,所以我们定义了一个覆盖路径长度十分之一的区域
对于(int i=0;ilistFloat.get(i)-areaLength
&&touchXlistFloat.get(i+1)-区域长度
&&touchY
这些连续区域以更高的精度捕捉触摸事件,更接近路径:。
可以通过使用
Rect
类来改进此方法,以确保这些区域不相互重叠,并以更高的精度绑定起点和终点。

这可以识别路径周围而不是多段线上给定边界多边形中的触摸事件。确切地说,我所寻找的并不重要。我保存了每个接触点是为了我自己的目的。很显然,在onDraw中创建新的RectF和区域对性能不好,如果可能的话可以更好地重用。我有另一个路径而不是事件(x,y),所以我如何检查我的一个路径是否在当前路径内?是的,但您仅限于API 19和更高版本。还有其他解决方案吗?谢谢,我已经通过对路径进行子类化并跟踪所有点来解决它,然后我使用了这个公式并将其改写为Java。我想如果您愿意,我可以发布一个完整解决方案的答案。我不确定这是否对任何人都有帮助。这个答案不起作用。也许这是故意的行为,也许是一个bug。我使用
Path.op(uuu,Path.op.INTERSECT)
查看路径是否与以(x,y)为中心的小矩形相交,并且当(x,y)相对靠近路径,但不在路径内部时,它有时会返回非空的交点。注意,我的路径是由直线组成的,有时直线会自行延伸。还要注意,这不仅仅是因为我为
op()
创建的“小矩形”不够小@巴坦多我对你的解决方案感兴趣你能把答案贴出来吗?
float areaLength = pathMeasure.getLength() / 20; // since we collect ten points, we define a zone covering a tenth of path length    
for (int i = 0; i < listFloat.size() - 1; i += 2) {
    if (touchX > listFloat.get(i) - areaLength
     && touchX < listFloat.get(i) + areaLength
     && touchY > listFloat.get(i+1) - areaLength
     && touchY < listFloat.get(i+1) + areaLength) {
        Log.d(TAG, "path touched");
    }

}