Android: Как проверить, содержит ли путь точку касания? - PullRequest
18 голосов
/ 06 марта 2012

Я бы попытался разработать приложение, в котором я могу нарисовать планиметрию. Итак, у каждой комнаты есть свой ID или name , и, если я коснусь комнаты, я хочу показать сообщение с этим идентификатором или именем. Проблема в том, как проверить, если и какой путь затронут !!

Я видел много тематических обсуждений, которые говорили об этой проблеме. Кто-то говорит, что следует использовать метод getBounds и после этого содержит метод для проверки, находится ли точка касания в Rect. Но, я думаю, метод getBounds возвращает наименьший Rect, содержащий путь, верно?

Итак, комнаты имеют разные пользовательские геометрические формы, и по этой причине, если я получу границы около 2 близких комнат, метод может вернуть общий набор точек. Плохой! В каждой комнате есть только свои баллы. Как я могу решить эту проблему?

В iOS я мог бы использовать PathContainsPoint метод, но, к сожалению, Android Path не имеет ничего подобного.

Я надеюсь, что кто-то может мне помочь Спасибо заранее

Ответы [ 3 ]

41 голосов
/ 14 мая 2012

Хорошо, я решил свою проблему. Выкладываю пример кода:

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;
}
3 голосов
/ 11 декабря 2018

Как сказал Эдвард Фальк, лучший способ - использовать path.op () , потому что Region является квадратным. И одна точка может быть в 2 или 3 регионах. Например: введите описание изображения здесь Все регионы будут содержать синюю точку, но на самом деле только путь4 содержит эту точку.

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;
}
1 голос
/ 20 ноября 2015

Вот мысль: создайте новый путь, представляющий собой крошечный квадрат вокруг точки, к которой вы прикоснулись, а затем пересекайте этот путь с вашим путем, который нужно проверить, с помощью path.op () и посмотрите,результат пуст.

...