Как я могу сказать, еслизамкнутый путь содержит данную точку ?

? Tom Seago @ | Original: StackOverFlow
---

В Android, у меня есть путь объекта, который я знаю, определяет замкнутый путь, и мне нужно, чтобы выяснить, еслиданная точка находится внутри контура. То, что я надеялся на что-то вдоль линий

path.contains (INT х, Int у)

но это, кажется, не существует.

Конкретная причина Я ищу это потому, что у меня есть коллекция фигур на экране, определенных в качестве путей, и я хочу, чтобы выяснить, какойпользователь нажал на . Если естьлучший способ, приближается это такое, как с помощью различных элементов пользовательского интерфейса, а не делать это "трудный путь " я, я открыт для предложений.

Я открыт для написания алгоритма себе, если у меня есть, но это означает, что различные исследования я думаю.

---

Top 5 ответ

1Brian @

Класс android.graphics.Path не имеет такой способ. Класс Canvas действительно есть область отсечения, которая может быть установлена ​​на путь, нет никакого способа, чтобы проверить его против точки. Вы можете попробовать Canvas.quickReject, тестирование на одной точке прямоугольника (или 1x1 Rect ). Я не знаю, если это будет действительно проверить против пути или просто ограничивающий прямоугольник, однако.

Класс Регион ясно только отслеживает, содержащей прямоугольника.

Вы можете рассмотреть возможность использования каждого из ваших регионах в 8- битным альфа слоя Bitmap друг с Path заполняется в его собственном значении ' ' Цвет (убедитесь, что сглаживание выключено в вашем Paint ) . Это создает своего рода маски для каждого пути, заполненной с индексом на путь, который заполнил его. Тогда вы могли бы просто использовать значение пиксела в качестве индекса в списке путей.

Bitmap lookup = Bitmap.createBitmap(width, height, Bitmap.Config.ALPHA_8);
//do this so that regions outside any path have a default
//path index of 255
lookup.eraseColor(0xFF000000);

Canvas canvas = new Canvas(lookup);
Paint paint = new Paint();

//these are defaults, you only need them if reusing a Paint
paint.setAntiAlias(false);
paint.setStyle(Paint.Style.FILL);

for(int i=0;i<paths.size();i++)
    {
    paint.setColor(i<<24); // use only alpha value for color 0xXX000000
    canvas.drawPath(paths.get(i), paint); 
    }

Тогда посмотрите очков,

int pathIndex = lookup.getPixel(x, y);
pathIndex >>>= 24;

Будьте уверены, чтобы проверить 255 ( без пути ), если есть невыполненные пункты .

2Randy Findley @

Вот то, что я сделал, и это, кажется, работает :

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

Теперь вы можете использовать region.contians метод (X, Y ) .

Point point = new Point();
mapView.getProjection().toPixels(geoPoint, point);

if (region.contains(point.x, point.y)) {
  // Within the path.
}

** Обновление на 6/7/2010 ** Метод region.setPath вызовет мое приложение не к краху ( без предупреждающего сообщения), еслиrectF слишком велик. Вот мое решение :

// Get the screen rect.  If this intersects with the path's rect
// then lets display this zone.  The rectF will become the 
// intersection of the two rects.  This will decrease the size therefor no more crashes.
Rect drawableRect = new Rect();
mapView.getDrawingRect(drawableRect);

if (rectF.intersects(drawableRect.left, drawableRect.top, drawableRect.right, drawableRect.bottom)) {
   // ... Display Zone.
}
3Jesse Wilson @

Http://www.opensource.apple.com/source/WebCore/WebCore-658.28/platform/graphics/skia/SkiaUtils.cpp в WebKit имеет C ++ работы вокруг ошибки Рэнди Финдли в :

bool SkPathContainsPoint(SkPath* originalPath, const FloatPoint& point, SkPath::FillType ft)
{
  SkRegion rgn;
  SkRegion clip;

  SkPath::FillType originalFillType = originalPath->getFillType();

  const SkPath* path = originalPath;
  SkPath scaledPath;
  int scale = 1;

  SkRect bounds = originalPath->getBounds();

  // We can immediately return false if the point is outside the bounding rect
  if (!bounds.contains(SkFloatToScalar(point.x()), SkFloatToScalar(point.y())))
      return false;

  originalPath->setFillType(ft);

  // Skia has trouble with coordinates close to the max signed 16-bit values
  // If we have those, we need to scale. 
  //
  // TODO: remove this code once Skia is patched to work properly with large
  // values
  const SkScalar kMaxCoordinate = SkIntToScalar(1<<15);
  SkScalar biggestCoord = std::max(std::max(std::max(bounds.fRight, bounds.fBottom), -bounds.fLeft), -bounds.fTop);

  if (biggestCoord > kMaxCoordinate) {
      scale = SkScalarCeil(SkScalarDiv(biggestCoord, kMaxCoordinate));

      SkMatrix m;
      m.setScale(SkScalarInvert(SkIntToScalar(scale)), SkScalarInvert(SkIntToScalar(scale)));
      originalPath->transform(m, &scaledPath);
      path = &scaledPath;
  }

  int x = static_cast<int>(floorf(point.x() / scale));
  int y = static_cast<int>(floorf(point.y() / scale));
  clip.setRect(x, y, x + 1, y + 1);

  bool contains = rgn.setPath(*path, clip);

  originalPath->setFillType(originalFillType);
  return contains;
}
4Cal Hinshaw @

Я знаю, чтонемного опоздал на вечеринку, но я бы решить эту проблему, думая о нем, как определения, находится литочка в полигоне .

http://en.wikipedia.org/wiki/Point_in_polygon

Математика вычисляет более медленно, когда вы смотрите на кривых Безье, а не отрезками, но рисунок луч отточки до сих пор работает .