Найти узлы решётки, принадлежащие телу.
off-lattice вершинамиможешь пояснить, что это значит?
точное решение можно получать с помощью библиотеки ISL (гуглить "integer set library") или, возможно, polylib и PPL (Parma polyhedra library)
в ISL можно задать выпуклое тело как пересечение полупространств и спросить все целые точки, попавшие в него
Можно попробовать экстраполировать на трехмерное тело.
Тут тело выпуклое, так что ситуация вообще шикарная.
посчитать количество пересечений с границей тела. Если нечетное - то точка внутри, если четное - то снаружи.Только нужно ещё учитывать, что этот отрезок может пересечь границу тела в вершине. При этом точка пересечения одна, но интересующая нас точка может быть как снаружи тела, так и внутри него.
Тут тело выпуклое, так что ситуация вообще шикарная.Да ещё и многогранник!
В общем, если тело — выпуклый многогранник, то каждый треугольник, который задаёт часть его поверхности, задаёт плоскость. Нормаль к этой плоскости мы можем найти.
Задача сильно упрощается, если известно ещё и по какую сторону от каждой плоскости лежит тело. (Это также легко можно вычислить: взять вершину многогранника, которая не лежит на плоскости, и посчитать с какой стороны от плоскости она располагается — см. ниже.)
Так вот. Считаем, что у нас есть для каждого треугольника набор трёх чисел — координаты вектора нормали, направленной внутрь тела.
Берём произвольную точку (про которую хотим понять где она лежит) — набор трёх её координат (x, y, z).
Для каждой нормали (nx, ny, nz) считаем h = x * nx + y * ny + z * nz. Если h < 0, то точка точно снаружи. Если h = 0, то точка лежит на плоскости.
Таким образом, если есть хотя бы одно отрицательное h для какой-либо нормали, то точка лежит вне тела. Если все h положительные, то точка лежит внутри тела. Если все h неотрицательные и при этом есть хотя бы одно h равное нулю, то точка лежит на поверхности тела.
Если тело не меняется во времени или довольно редко меняется (по сравнению с частотой подсчётов положения точек относительно данного тела то следует все нормали посчитать заранее и пользоваться расчётами, которые я привёл. Это быстро и довольно точно (погрешность только из-за неточных представлений чисел с плавающей точкой).
ЗЫ
h, получаемое по приведённой выше формуле, — расстояние от точки до плоскости умноженное на длину вектора нормали.
Не, это круто, но тут не учитывается, что нам надо не принадлежность произвольных точек считать, а именно точек сетки. Например, если (0, 0, x) и (0, 0, y) принадлежат этому многограннику (выпуклому то все промежуточные заведомо тоже. Поэтому полный перебор не особо может сгодиться, хотя зависит от чисел в задаче.
Для этого для каждой пары целых x,y нужно найти 2 треугольника (верхний и нижний проекции которых на плоскость XY содержат точку (x,y). Короче задача сводится к нахождению точек решетки внутри треугольника на плоскости.
ну да, в принципе, если знать ограничивающий параллелепипед всей фигурки, то можно довольно эффективно реализовать.
Не, это круто, но тут не учитывается, что нам надо не принадлежность произвольных точек считать, а именно точек сетки.Да, это в описанном мной методе никак не учитывается.
полный переборГде ты увидел полный перебор?
Там для каждого треугольника считается число (три умножения и два сложения). Но нам, в принципе, не обязательно вычислять все эти числа, если хотя бы одно будет отрицательным.
Где ты увидел полный перебор?ну а как ты от метода определения принадлежности точки телу перейдешь к подсчету количества этих точек?
Подумал, что надо быстро определять принадлежит ли точка телу или нет.
Спасибо. Я примерно так и делаю, только, помимо определения, по какую сторону от граней лежит точка, я зачем-то проверяю, есть ли пересечение вектора из условного "центра" тела в данную точку с данной гранью (а не только с её плоскостью). Действительно, эта проверка, похоже, нафиг не нужна, она делается потому, что в другом месте программы я ищу именно пересечение с гранью, и использую ту же функцию. Попробую сделать отдельную функцию для проверки принадлежности точки тела без проверки: сейчас это самое жрущее место в программе, поглощает 80% всего времени, и любая оптимизация будет полезна. Огромное спасибо.
Так что я просто попробую ваш метод и сравню. В любом случае, спасибо.
При выпуклом теле, кстати, можно воспользоваться OpenGL, отрисовав объект с нескольких сторон и проанализировав, какие узлы нарисовались.
Вот, кстати, идейка, которую можно попробовать развить.
Если у нас вершины выпуклого многогранника задаются координатами (xi, yi, zi i = 1, ..., n, то любая внутренняя его точка задаётся координатами \sum_i ki (xi, yi, zi причём k_i >= 0 и \sum_i ki = 1.
а ISL чем-то не устроил?
1. Выбирается несколько плоскостей объекта, образующих замкнутый объект. От 4-х до 6.
2. Вычисляется узлы внутри полученного объекта.
3. Поток к этому набору применяются по одной остальные плоскости. По ходу удаляя из начального набора узлы, которые не прошли проверку.
Тут тело выпуклое, так что ситуация вообще шикарная.а шо, бывает вогнутое тело?
Оставить комментарий
Inflict84
Тело (условно говоря, односвязное выпуклое - например, смахивающее на немного смятый шар, хотя в идеале любое) живет в дискретной трехмерной решётке. Поверхность тела задана треугольниками с off-lattice вершинами. Надо узнать, какие узлы решётки находятся внутри тела, и сделать это как можно более быстрыми вычислениями. В принципе, 100%-ная точность определения принадлежности точки телу не требуется, но желательна.Буду признателен за советы,
Заранее спасибо.