У меня есть система, где вы можете щелкнуть один раз, чтобы разместить узел на сцене. Когда вы размещаете 3 узла, он образует треугольник. Когда вы размещаете какие-либо будущие узлы, он создает новый треугольник, соединяя этот узел с двумя ближайшими существующими узлами.
Это прекрасно работает в большинстве случаев, но имеет недостатки при использовании вблизи треугольников с очень острыми углами, потому что один из двух ближайших узлов часто не тот, который следует использовать.
Например, см. Изображение ниже. Пурпурный треугольник - первый. Если я затем щелкну в позиции, помеченной X, то получу новый треугольник с наложенным синим цветом. То, что я хочу, это новый треугольник, где зеленый оверлей. (т.е. симметрично пурпурному, в этом примере. Уточнение: зеленый и пурпурный треугольники не перекрываются - зеленый простирается под синим до самого левого узла)
Как я могу определить, какие 2 существующие вершины использовать при создании новых треугольников, чтобы треугольники не накладывались таким образом?
РЕДАКТИРОВАТЬ : Поиск ближайшего края дает лучшие результаты, но не идеальные. Рассмотрим эту ситуацию:
Тест «ближайший край» неоднозначен и может возвращать AB или AC (поскольку ближайшая точка к X для обоих находится в точке A). Желаемый результат будет AC, чтобы сформировать треугольник ACX без наложения ребер. Как я мог обеспечить этот результат? (Я бы предпочел не выполнять отдельные тесты перекрытия ребер в качестве прерывателя связей, если это возможно, поскольку я обеспокоен тем, что тест ближайшего ребра не обязательно определит, что 2 точно равноудалены, учитывая проблемы точности с плавающей запятой.)
Ответы:
Вместо того, чтобы находить минимальное расстояние до узлов, найдите минимальное расстояние до края (то есть отрезок линии, определенный узлами).
Затем, если ближайшая точка - это вершина (которую вы должны будете использовать с помощью теста epsilon ** с плавающей точкой), сравните угол между линией от новой точки до вершины и каждым из ребер, соединенных с этой вершиной. Выберите тот с минимальным абсолютным углом:
** Чтобы избежать добавления вырожденных треугольников, которые могут нарушить тест эпсилон, вы можете захотеть поместить область вокруг каждой вершины, где добавление точек запрещено, (что-то вроде запрета точек внутри некоторого кратного эпсилона, использованного выше).
источник
После размещения первого треугольника при размещении новой вершины вы всегда будете генерировать два новых ребра. Третье ребро для нового треугольника всегда будет общим ребром с предыдущим треугольником. Если бы вы могли найти способ определения общего ребра, вы бы знали, к каким вершинам подключаться, но это сложная часть. Я полагаю, что один из способов сделать это, нарисовав линию от вашей новой вершины до центра каждого из последних трех сгенерированных ребер (или, возможно, 3 ближайших ребер).
Если линия от вашей вершины до центра ребра не пересекает ни одно из двух других ребер, у вас есть общее ребро. Общий край скажет вам, с какими двумя вершинами соединить вашу новую вершину.
Джимми привел аргумент в пользу неоднозначной точки зрения относительно того, куда пойдет новый треугольник:
Это даст вам возможность выбирать между двумя действительными треугольниками. Возможно разрыв связи, центральная точка которого является самой близкой.
Учитывая ваше обновление, хотя и более сложное, моё решение приведет к связям, только если у вас есть два правильных треугольника. Используя этот метод, ваш второй пример изображения даст желаемый результат.
источник
Имея свой пурпурный треугольник ABC, вы включаете новую вершину X. Я думаю, очевидно, что будут две прямые, начинающиеся с D, которые не будут пересекаться между какими-либо краями треугольника ABC.
Эти две линии могут быть AX & BX, BX & CX или AX & CX. Затем вы можете рассматривать вашу проблему как классическую проблему «пересекаются ли две линии»? Затем вы можете проверить, какая из этих пар линий не пересекается ни с одним из ребер треугольника ABC, следуя, например, любому из методов из этого вопроса . Следовательно, у вас будут два новых ребра нового треугольника.
источник
Выяснить, находитесь ли вы в одной из однозначных областей (1, 2, 3 ниже), довольно легко: обработайте каждый край вашего треугольника как 2D-плоскость и проверьте, на какой стороне плоскости находится ваша новая точка. Если вы находитесь внутри двух из них, но снаружи одного, то этот соответствует краю треугольника, который добавляет две вершины в ваш новый треугольник.
Если вы находитесь внутри одного и снаружи двух, вы находитесь в неоднозначном случае, когда ближайшая часть треугольника к вашей новой точке является углом. В этом случае вы можете сформировать 2D-плоскость из средней точки противоположного края (той, в которой вы находитесь) и ближайшей вершины (той, которая разделена между двумя плоскостями, вне которых вы находитесь). Вы можете выбрать ребро в зависимости от того, на какой стороне этой плоскости находится ваша новая точка.
Обратите внимание, что тест плоскости в 2D работает так же, как и в 3D: поставьте точку вектора из любой точки плоскости в точку с нормалью плоскости (в 2D это перпендикуляр линии).
(Между прочим, разделенные пурпурным цветом области на этом изображении называются областями Вороного; это области пространства, содержащие точки, наиболее близкие к определенному объекту - ребру или вершине - треугольника. Редактировать: моя терминология здесь на самом деле не совсем Совершенно верно, это не совсем Вороной регионы.)
источник