Я пытаюсь заполнить файл STL точками в Fortran. Я написал базовый код, но он не работает.Fortran - Point in STL
Мой метод заключается в использовании генератора случайных чисел для генерации точки. Затем я нормализую эту точку к размерам ограничивающего прямоугольника STL.
Затем я выбрасываю координату «z» для первого треугольника в STL. Я проверяю, является ли случайная точка с максимальным и минимальным значением координаты «x» и «y» первого треугольника. Если это так, я проектирую случайную точку вертикально на плоскость треугольника и вычисляю значение «z», если оно пересечет плоскость. Затем я проверяю, меньше ли значение z случайной точки, чем значение прогнозируемой точки (лучевое кастинг). Если да, я увеличиваю счетчик, который первоначально установлен на ноль, на единицу.
Я делаю это для каждого треугольника в STL. Если счетчик равен даже случайной точке за пределами тома, если это нечетно, случайная точка находится внутри тома, и точка сохраняется.
Затем я создаю новую случайную точку и начинаю снова. Я включил важный код ниже. Извинения за длину (много комментариев и пустых строк для удобочитаемости).
! Set inital counter for validated points
k = 1
! Do for all randomly generated points
DO i=1,100000
! Create a random point with coordinates x, y and z.
CALL RANDOM_NUMBER(rand)
! Normalise the random coordinates to the bounding box.
rand(1:3) = (rand(1:3) * (cord(1:3) - cord(4:6))) + cord(4:6)
! Set the initial counter for the vertices
j = 1
! Set the number of intersections with the random point and the triangle
no_insect = 0
! Do for all triangles in STL
DO num = 1, notri
! Get the maximum "x" value for the current triangle
maxtempx = MAXVAL(vertices(1,j:j+2))
! Get the minimum "x" value for the current triangle
mintempx = MINVAL(vertices(1,j:j+2))
! If the random point is within the bounds continue
IF (rand(1)>=mintempx .AND. rand(1)<=maxtempx) THEN
! Get the maximum "y" value for the current triangle
maxtempy = MAXVAL(vertices(2,j:j+2))
! Get the minimum "y" value for the current triangle
mintempy = MINVAL(vertices(2,j:j+2))
! If the random point is within the bounds continue
IF (rand(2)>=mintempy .AND. rand(2)<=maxtempy) THEN
! Find the "z" value of the point as projected onto the triangle plane
tempz = ((norm(1,num)*(rand(1)-vertices(1,j))) &
+(norm(2,num)*(rand(2)-vertices(2,j))) &
- (norm(3,num)*vertices(3,j)))/(-norm(3,num))
! If the "z" value of the randomly generated point goes vertically up
! through the projected point then increase the number of plane intersections
! by one. (Ray casting vertically up, could go down also).
IF (rand(3)<= tempz) THEN
no_insect = no_insect + 1
END IF
END IF
END IF
! Go to the start of the next triangle
j = j + 3
END DO
! If there is an odd number of triangle intersections not
! including 0 intersections then store the point
IF (MOD(no_insect,2)/=0 .AND. no_insect/=0) THEN
point(k,1:3) = rand(1:3)
WRITE(1,"(1X, 3(F10.8, 3X))") point(k,1), point(k,2), point(k,3)
k = k + 1
END IF
END DO
Мои результаты были полным мусором (см изображения) Изображение 1 - Тест STL файл (корабль взят из here). Часть программы (код не показан) читается в двоичных файлах STL и сохраняет нормали поверхности каждого треугольника и вершины, составляющие этот треугольник. Затем я написал вершины в текстовый файл и вызываю GNUPLOT для соединения вершин каждого треугольника, как показано выше. Этот график является просто испытанием, гарантирующим, что файлы STL будут считаны и сохранены правильно. Он не использует поверхностные нормали. . Изображение 2 - Это график точек кандидата, которые были приняты как находящиеся внутри тома STL. (Сохраняется в последнем цикле if, показанном в коде выше). Затем эти принятые точки затем записываются в текстовый файл и отображаются с помощью GNUPLOT (NOT SHOWN). Если бы алгоритм работал, этот график должен быть облаком точек триангулированной сетки, показанной выше. (Он также отображает 8 границ прямоугольника, чтобы гарантировать, что случайные частицы сгенерированы в правильном диапазоне)
Я ценю, что это не учитывает точки, созданные на вершинах или лучах, которые параллельны и пересекаются с ребрами. Я просто хотел начать с грубого кода. Не могли бы вы посоветовать, есть ли проблема с моей методологией или кодом? Дайте мне знать, если вопрос слишком широк, и я удалю его и постараюсь быть более конкретным.
Не могли бы вы прокомментировать изображения.Что они показывают> Являются ли оба результата вашего кода? –
@VladimirF, я добавил некоторые комментарии к вышеуказанным изображениям. Короче - Image 1 представляет собой общую триангулированную сетку, которая была прочитана программой, а затем построена для обеспечения правильного хранения. Изображение 2 предназначено для построения одного и того же объема, заполненного точками (то есть случайных точек, которые были проверены с использованием вышеприведенного кода и оказались внутри триангулированной сетки). – 1QuickQuestion
Итак, что вам нужно, чтобы проверить, находится ли точка внутри не выпуклого многогранника? Для этого я бы использовал библиотеку. Я использую CGAL для чтения OFF-файла, но он не возвращается внутри или нет напрямую, тогда мне приходится подсчитывать количество пересечений с лучом. Как насчет http://gts.sourceforge.net/? –