Чтобы рассмотреть вашу проблему, мы должны сначала рассмотреть, что означает внутри или снаружи. С четырьмя поверхностями, каждая поверхность делит пространство ровно на две стороны, и в общем случае четыре поверхности делят пространство в 9 областях, только одна из которых ограничена, ограничивая тетраэдр (но если мы тщательно выберем поверхности, мы можем достичь даже без ограниченной области - например, сделать два из них параллельными). Таким образом, в общем, вы должны решить, какая из сторон плоскостей будет обозначать внутреннюю или внешнюю (ну, это тоже не имеет значения, поскольку внешность такая же, как и не внутри).
С большим количеством лиц проблема усложняет (и усложняет ее), так как вы можете иметь несколько ограниченных областей, которые также определяют твердые тела, поэтому вам нужна дополнительная информация, что только плоскости, которые ее ограничивают.Проблема даже усложняет ситуацию, если регион приводит к не выпуклой области, потому что ваша точка может быть в какой-то части вашего региона, которая соответствует с одной стороны для некоторых самолетов и в неправильной стороне для других, и продолжайте быть внутри вашего твердого тела. Просто увидеть разделители многоугольника, как этого
и возможности создания ограниченных областей
Первое, что вам нужно, чтобы адекватно определить ваши твердое тело, ограничивающее лицо с ребрами и несколько устанавливая ребра и вершину, которые ограничивают одно лицо, как лица соединяются, чтобы сформировать ваше тело.
После того как вы эта ситуация, у вас есть набор граней, и векторы, указывающие на вне для каждого лица (в немигающей манере, так что вы не до конца с нормалями направлены вверх, и следующий указывая вниз). Следующее, что вам нужно сделать, это разделить ваше тело на выпуклое тело. Можно показать, что для трехмерного твердого тела, выполненного из гладких граней, его можно разбить на конечный набор выпуклых тел.
Я попытаюсь проиллюстрировать ту же проблему в 2D, но по сути это то же самое в 3D:
Во-первых, у нас есть начальное Полигон, давайте предположим, что оно выпукло (это важное свойство для этого я укажем ниже):
Предположим, что это 3D-астероид, и вы - кто-то, кто идет по его поверхности. Если вы начнете ходить, вы пройдете все линии, выраженные желтым цветом. Это нормали, и для этого вам нужно знать с каждого лица, с которыми сталкиваются лица, и построить на этих поверхностях карту нормалей, как я сделал. Когда вы ходите по астероиду, вы отмечаете нормали, чтобы знать, где находится внутренняя часть астероида, и вы это ограничиваете. Теперь у нас есть карта нашего астероида со всеми нормалями. Давайте проведем полупространство под нами (одна сторона поверхности, которая ниже нас). В геометрии это может быть представлено плоскостью (плоскость обладает тем свойством, что все ее точки ортогональны вектору, поэтому X*V=0
где *
представляет точку Если мы возьмем центр нашего полигона и нормальный вектор в качестве желтого вектора на нашем рисунке, мы получим (X - P)*N = 0
, где X
- это положение точки в плоскости, P
- это наше положение (центр лица) и N
вектор нормали к плоскости, указывая вверх (на внешней стороне астероида)
Ну, это уравнение обладает свойством, что если мы подставим X
любым положением в пространстве, все точки X
ниже самолет значение (X - P)*N < 0
и все значения неба имеют его > 0
.
Если бы я сделать то же самое для четырех нормалей, я получаю это: ... дело в и точкой в вопросе X
будет похоронен в астероид, только если четыре самолета дайте (X - X_face)*(N_face) < 0
, где сейчас X_face
- это центр лица, а N_face
- лицо, нормальное, указывающее наружу от нашего астероида. Точка будет находиться внутри астероида только, если применяются четыре условия.
Но что произойдет, если астероид не выпуклый?
Если вы рисуете нормали, это не поможет ... так как есть точки, которые находятся внутри астероида и терпят неудачу некоторые из тестов (помните, что точка должна быть ниже всех поверхностей, но не (как показано ниже):
проблема состоит в том, что многоугольник (или многогранник) не является выпуклой, и мы не можем применить алгоритм там Итак, сначала мы должны решить эту проблему. что он выпуклый.
Если вы начинаете следовать всей поверхности астероида (сохраняя нормали), когда вы пересекаете край, вы попадаете в другую плоскость, которая увеличивает или уменьшает наклон, поэтому, если она увеличивает наклон, вы помечаете это ребро (вершина в нашем полигоне), так и аномальные (мы обозначили их в красный цвет), и если он падает, мы будем отмечать их как нормальные (мы обозначили их в зеленый цвет):
Когда все ребра являются нормальными, нет проблем, так как наш астероид будет выпуклым, но когда какой-либо из них является аномальным, мы должны продолжать в этой плоскости (копать в астероиде на всей плоскости), пока не доберемся до другой поверхности (мы продлили плоскость до разделения наш полигон) как таковой:
как мы имеем конечное число ребер, и только некоторые из них были отмечены как аномальное, этот процесс является оправданным, чтобы закончить (помните, что вы можете получить другая сторона пытается найти лицо (сторона) вашего многогранника (многоугольника) с вершинами вверх и вершины вниз (в том смысле, который мы объясняли ранее))
поэтому вы разделили ваш многогранник на конечный набор выпуклых многогранников, который может быть применен к первому алгоритму.
Я согласен с этим решением, но то, что я искал был общий алгоритм, который не включает в себя большую часть линейной алгебры и может быть реализован так, как луч литья реализуется в 2D. –
@AnkitMishra Как лучевое литье не связано с линейной алгеброй? – immibis
Да, но он делает это очень просто, он вычисляет наклон точек (P0, P1) и (P1, P2) и завершается, если он по часовой стрелке или против часовой стрелки. Итак, вот почему я пытался это сделать, сравнить наклон и посмотреть, не отличается ли ориентация двух точек на линии w.r.t линий, образующих поверхность, тогда эта линия пересекает этот отрезок. Но я не уверен, как это сделать в 3d-пространстве. –