В настоящее время я пытаюсь определить силуэт края трехмерного объекта. Я знаю, что вы должны сначала определить, смотрится ли лицо в определенном положении, а затем найти края, которые являются общими для передней и задней поверхностей. Я был в состоянии разобраться с вещами спереди и сзади, но я не могу понять, как найти, разделяются ли края без ALOT операторов if. мои данные вершин хранятся из x1, z1, y1, x2, z2, y2, x3, z3, y3 для каждого многоугольника. Если бы кто-нибудь мог помочь решить мою ужасную линию, если это дерьмо, это было бы здорово.
Благодарю.
Если вы спрашиваете, как определить, находятся ли два отрезка на одной линии, вы можете использовать немного евклидовой геометрии. Давайте рассмотрим пару определений:
точка А это н-кортеж (a1, a2, ..., an)
действительных чисел. В 3D случае n=3
,
Скалярное умножение точки А и действительного числа t
определяется как
tA = (t*a1, t*a2, ..., t*an)
С этими двумя идеями мы можем легко представить линию. За два очка A
а также B
, точка P
который удовлетворяет уравнению
P = tA + (1-t)B
на линии AB
где t
это реальное число.
когда 0 <= t <= 1
, P
лежит между A
а также B
с P=A
когда t=1
а также P=B
когда t=0
,
Теперь, чтобы поместить это в перспективу программирования, вы можете создать два класса: Point
а также Line
, Используя приведенное выше уравнение, очень легко определить, является ли Point
лежит на заданном Line
, Чтобы определить, находятся ли два отрезка на одной линии, просто используйте два Point
которые определяют один Line
и проверьте, если они лежат на другом Line
,
если 2 отрезка совпадают
Два отрезка линии одинаковы, если они используют одинаковые координаты точки или идентичные индексы точки. Проверка, находятся ли они на одной линии, — это совершенно другая проблема, которую вам не нужно решать, чтобы найти силуэт.
Индексированные примитивы означают, что
1. вы храните все точки в массиве (std::vector<vector3> points;
или что-то подобное, где vector3
это тип данных, в котором хранятся координаты XYZ), и каждая точка уникальна.
2. грани и ребра относятся к точкам, используя целочисленные индексы точек.
То есть
struct Vec3{
float x, y, z;
};
typedef unsigned int Index;
struct Face{
enum{vertsPerFace=3};
Index verts[vertsPerFace];
};
struct Edge{
enum{vertsPerEdge=2};
Index verts[vertsPerEdge];
};
Когда вы загружаете модель, вы строите список точек и конвертируете все грани в индексированные примитивы, используя std::set
std::map
или подобные структуры. После того, как вы проиндексировали примитивы, вы можете создавать ассоциативные таблицы (используя std :: map), которые бы отображали ребро в список граней. std::multimap<std::pair<Index, Index>, FaceIndex>
, сопоставить ребра с индексами граней, которые используют эти ребра std::map<std::pair<VertexIndex, VertexIndex>, FaceIndex>
и так далее.