Нарисуйте 2D лицо с 3D вершинами - PullRequest
1 голос
/ 24 апреля 2019

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

Я разрабатываю программу, которая читает лица на 3D-модели.Каждая грань нарисована путем соединения серии из 3 или 4 вершин в координатах XYZ.Моя программа (или, по крайней мере, намерение) будет проходить через каждое лицо, накладывать изображение текстуры на лицо и сохранять изображение.Я могу обработать последние две части, но у меня возникают проблемы с отображением лица на двухмерную поверхность.У меня нет доступа к нормальным, что я считаю, помогает.(Вершины квадов всегда будут лежать в одной плоскости, поэтому квады не будут согнуты).

Face in 3D space

до

Face in 2D space

Потенциальные решения, о которых я думал (но понятия не имею, как реализовать):

  1. Используя 2 вершины, вычислите угловыеотклонение от оси (например, использование двух верхних вершин квадрата для вычисления вращения Y).Using delta X and delta Y to calculate rotation Y После этого для всех трех осей я могу повернуть вершины на противоположные повороты, чтобы, надеюсь, сделать его плоским (я не знаю, как это сделать математически).Однако проблема, которую я вижу с этим решением, состоит в том, что координата x может быть изменена на 2 поворота (y и z), а не только на 1 (и то же самое относится к координатам y и z).
  2. Вместо повороталицо, я воссоздаю форму.Как и в решении 1, я использую две вершины.Вместо того, чтобы вычислять вращение, я вычисляю длину и наклон ege.Затем я могу нарисовать ту же линию в 2D-пространстве и повторить для других ребер.Я нахожу наклоны ребер, чтобы правильно определить углы на пересекающихся ребрах (подумайте о полярных координатах).У меня есть идея, как это сделать, но я не уверен, что это лучшее решение.

Ответы по коду принимаются, но, думаю, не обязательно.(VB, C #, JS, независимо от ваших предпочтений) Я хотел бы знать математику того, что я делаю.Тщательные объяснения приветствуются.

Ответы [ 2 ]

1 голос
/ 24 апреля 2019

Чтобы получить 2D координаты для точек на грани, вам нужно два ортогональных единичных вектора в одной плоскости.Давайте назовем их u и v .Тогда для каждой 3D-точки p на плоскости ее 2D-координаты составляют (uv, vp) , где '.'является точечным произведением.

Сначала вычислите нормаль к поверхности.Произойдет перекрестное произведение любых двух векторов на плоскости.Возможно, вы захотите обойти и сложить перекрестные произведения каждого угла на лице, чтобы усреднить любые ошибки.Нормализуйте длину нормали до 1 и назовите ее n .

Теперь нам нужен произвольный вектор, ортогональный к нормали.Выберите ось с наименьшей координатой в n , сделайте единичный вектор x вдоль этой оси, удалите ее компонент вдоль n (т.е. x -= n * (xn) ) и нормализуем его длину, чтобы получить u .

Затем просто возьмите перекрестное произведение n и u чтобы получить v .

1 голос
/ 24 апреля 2019

Одним из способов является вычисление поворота, которое отображает нормаль лица на (0, 0, 1).Применение этого вращения к лицу заставит его лежать в плоскости xy.

Чтобы вычислить нормаль лица, возьмите любые три точки p1, p2, p3 и вычислите

n = normalize((p2 - p1) x (p3 - p1)),

, где x - этоперекрестное произведение.

Тогда ось вращения:

rotAxis = n x (0, 0, 1) = (ny, -nx, 0)

Угол поворота:

cos rotAngle = n * (0, 0, 1) = nz
sin rotAngle = sqrt(1 - nz * nz)

Как только вы это сделаете, вы можете применить вращениек грани (например, путем преобразования вращения в матрицу вращения ).Затем просто отбросьте координату z.

В конце вы также можете выполнять 2D-преобразования, такие как переводы и 2D-вращение, как вам нравится.

...