Построение MKPolygon с использованием внешней границы набора координат-как разделить координаты, которые падают по обе стороны линии?
Я пытаюсь построить MKPolygon, используя внешнюю границу набора координат.
Из того, что я могу сказать, нет никакой поставленной функциональности для достижения этого в Xcode
(методы MKPolygon использовали бы все точки для построения многоугольника, включая внутренние точки).
Это занимает внешний лат координирует и проводит линию между ними. Оттуда вы разделяете свои точки на основе этой линии на два подмножества и обрабатываете расстояние между внешними латами, чтобы начать строить треугольники и удалять точки внутри, пока вы не останетесь с внешней границей.
Я могу найти внешние точки, просто посмотрев на min / max lat, и могу провести линию между ними (MKPolyline
) - но как я могу определить, падает ли точка на одну или другую сторону этой MKPolyline?
Следование вопрос в том, существует ли тест на попадание, чтобы определить, попадают ли точки в MKPolygon.
Спасибо!
1 ответ:
В итоге я использовал вариацию алгоритма подарочной упаковки. Конечно, не тривиальная задача.
Возникли проблемы с форматированием полного кода, так что мне придется просто поставить мои шаги (вероятно, лучше, потому что у меня есть некоторые очистки, чтобы сделать!)
Я начал с массива MKPointAnnotations
1) я получил самую низкую точку, которая дальше всего слева. Для этого я прошелся по всем точкам и сравнил lat/lng, чтобы получить самую низкую точку. Эта точка, безусловно, будет в выпуклости hull, поэтому добавьте его в NSMutableArray, который будет хранить наши выпуклые точки корпуса (cvp)
2) получить все точки слева от нижней точки и петлю через них, вычисляя угол cvp к оставшимся точкам слева. Тот, который имеет наибольший угол, будет точкой, которую вам нужно добавить к массиву.
Атан(вида COS(lat1)грех(lat2)-грех(lat1)*соѕ(lat2)*соѕ(lon2-lon1), грех(lon2-lon1)*соѕ(lat2))3) после того, как вы обработали все левые точки, создайте новый массив сравнения оставшихся точек, которые не были удалены или добавлены в корпус
Для каждой найденной точки создайте треугольник (используя lat from new точка и долго от предыдущей точки) и создать многоугольник. Я использовал этот код, чтобы сделать тест попадания на моем полигоне: BOOL mapCoordinateIsInPolygon = CGPathContainsPoint (polygonView.путь, NULL, polygonViewPoint, нет); Если что-то было найдено в тесте попадания, удалите его из массива сравнения (все те, что слева от исходного массива минус точки корпуса)
Как только у вас есть по крайней мере 3 точки в вашем массиве cvp, постройте еще один полигон со всеми cvp в массиве и удалите все, что в пределах использования теста попадания.
4) используйте те же вычисления и полигональные тесты для удаления точек и добавления найденных cvp В конце концов, у вас остается список точек, из которых состоит ваша выпуклая оболочка.