alexzzzz
> Не получится ли тогда ситуации, что красный отрезок будет более подходящей
> парой чёрному?
Говорю же, смещай. Чтобы например геометрический центр был в начале координат:

На плоскости получается следующая фигня. Если считать модуль разницы расстояний (хотя в этом уже нет смысла):

Если считать сумму расстояний:

Зелёная точка - геометрический центр/барицентр/среднее арифметическое вершин зелёного и чёрного отрезков. Красная - красного и чёрного.
--
Мысль такая: Если вместо честного расстояния между полигонами брать оценочную функцию, она должна непрерывно расти с ростом расстояния и расти (или как минимум не уменьшаться) при увеличении угла. Иначе постоянно встречаются комбинации, в которых выбираемая пара получается нелогичной.
alexzzzz
> Мысль такая: Если вместо честного расстояния между полигонами брать оценочную
> функцию, она должна непрерывно расти с ростом расстояния и расти (или как
> минимум не уменьшаться) при увеличении угла. Иначе постоянно встречаются
> комбинации, в которых выбираемая пара получается нелогичной.
Проблема в том, что понятие "расстояние между плоскостями" безсмысленно если плоскости не параллельны. Тебе же вроде как достаточно повторить более менее адекватное поведение, так? dot между нормалями плоскостей + смещение к геометрическому центру ограничивает нас, и delta D не сильно плавает за счет этого. Может попробовать пощупать как оно себя ведет в редакторе?
p.s. А если прям совсем заморочиться оценочной функцией - то можно попробовать опереться на площадь (для 3д случая объем)
типа площадь зеленой/серой трапеции помноженной на косинус угла между нормалями отрезков. Но я бы попробовал через delta D, мне кажется для редактора это более чем достаточно.
dot между нормалями не особо помогает. Ограничение должно быть или очень строгое, тогда в пары будут попадать только почти параллельные полигоны; или будет отсекать только совсем идиотские сочетания. На нижней картинке в предыдущем после угол между красным и черным отрезками всего 15 градусов (dot ~0,97). Я бы хотел рассматривать такие пары. И даже с 30 градусами хотел бы.
Можешь сам попробовать подвигать этот красный отрезок влево-вправо (модель для Geometry Expressions - Planes2). Расстояние от отрезка до условного центра координат (красной точки) плавает сильно, от 0 до >1.
По поводу площадей/объёмов, я боюсь, что с ними любой маленький полигон будет всегда выигрывать у любого большого (или наоборот, как условие поставишь).
alexzzzz
По поводу площадей я ничего не могу сказать. А вот совмещение плоскостей по delta D я лично использую, у меня в редакторе оно достаточно неплохо себя показало (но возможно у меня модели специфичные). Собственно поэтому я тебе и посоветовал его опробовать.
Допилил до работоспособной версии:

alexzzzz
> Допилил до работоспособной версии:
здорово выглядит. А как работает с невыпуклыми объектами?
p.s. Аутлайн как рисовал, в два прохода?
1. У меня все детали выпуклые, но могут объединяться в один составной объект, необязательно выпуклый. Составные объекты я пока не проверял, руки не дошли, но eсли не налажал, должны работать. Алгоритму должно быть пофиг на форму объекта.
2. Тупо отдельными отрезками поверх нарисованного.
alexzzzz
> 2. Тупо отдельными отрезками поверх нарисованного.
Я про штриховку. Думал ты на GPU её рисуешь вторым проходом с инвертированным DepthTest-ом. Ты на стороне CPU определяешь штриховать линию или нет?
Необходимость штриховки я определяю на CPU, тест глубины не использую. Если полигон смотрит на камеру, его линии всегда будут сплошными, независимо от того, перекрываются они другими объектами или нет.
Это отладочная графика, лишь бы рисовало, не важно как.
Составные объекты я пока не проверял, потому что нашлось чем дополнительно заняться даже на простых одиночных.
1. После поворота объекта, который выравнивает его относительно другого объекта-цели, я делаю ещё три сдвига, которые прижимают объект к цели. Первые два сдвига совмещают плоскости выбранных на объектах полигонов, чтобы зелёный полигон лежал на одной плоскости с другим зелёным, а розовый - на одной плоскости с другим розовым. Это просто и работает как нужно. Ещё остаётся третий сдвиг - вдоль линии пересечения зелёной и розовой плоскостей. С ним чуть сложнее.
Упрощённый пример на плоскости:
Два квадрата повёрнуты и придвинуты так, чтобы их зелёная сторона лежала на одной прямой (рисунок А). Теперь их надо как-то сдвинуть вдоль зелёной прямой, чтобы было логично, по принципу наименьшего удивления.
Сейчас я просто нахожу на объектах пару ближайших вершин, которые обе лежат на зелёной прямой, и сдвигаю объекты так, чтобы эти вершины совпали. Обычно работает, но довольно часто получается как на рисунке B, хотя я, когда хотел объекты совместить, ожидал, что получится как на рисунке C. Это раздражает. Надо изменить способ расчёта этого финального сдвига.
2. Ещё, пока проверял работу на практике, столкнулся с таким случаем:
Есть два объекта со скошенными углами, положены кривовато, как на картинке. Допустим, что это две соседние доски будущего забора.
Хочется, чтобы объекты соединялись сторонами CD/C'D', но иногда они соединяются сторонами BC/B'C'. Расчёт правильный: если расстояние одинаковое, а угол между BC/B'C' чуть меньше, чем между CD/C'D', то формально надо выбирать пару BC/B'C'. Но это правильно с точки зрения существующего алгоритма, а с точки зрения пользователя это бред.
Нужно, наверное, при сравнении углов дополнительно учитывать и площади полигонов, между которыми это угол.
alexzzzz
Попробуй учитывать площадь получающегося контакта — чем больше, тем лучше.
Тогда что п. 1, что п. 2 разрулятся автоматом.
Вспомнил ещё проблемку. Вроде как подвид первой проблемы, но напрягает отдельно.
3. Хотим пристыковать правый объект к левому по зелёной стороне:
Пока правый объект лежит криво, кажется, что после стыковки у объектов совпадут синие точки, потому что они ближе. Но если правый объект правильно повернуть, то ближними станут красные точки и именно ими такие объекты на практике стыкуются. Это вызывает удивление.
Как лучше лечить такое поведение, ещё не решил. Вижу два варианта:
а) вращать объекты не вокруг их центра, а вокруг, например, центра выбранного для стыковки полигона;
б) при поиске ближайших вершин брать не текущее расстояние между ними (после поворота), а изначальное.
Тема в архиве.