我正在尝试使用Fortran中的点填充STL文件。我写了一个基本代码,但它没有用。
我的方法是使用随机数生成器生成一个点。然后我将此点标准化为STL边界框的尺寸。
然后我扔出了" z" STL中第一个三角形的坐标。我检查随机点是否包含" x"的最大值和最小值。和" y"第一个三角形的坐标。如果是这样,我将随机点垂直投影到三角形平面上并计算" z"值应该与平面相交。然后我检查随机点的z值是否小于投影点的值(光线投射)。如果是,我将计数器(最初设置为零)增加1。我为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(不显示)绘制。如果算法有效,这个图应该是上面显示的三角网格的点云。 (它还绘制了8个边界框坐标,以确保在正确的范围内生成随机粒子)
我理解这并没有考虑在顶点上生成的点或平行并与边相交的光线。我只是想从粗略的代码开始。您能否告诉我的方法或代码是否有问题?如果问题太广泛,请告诉我,我会删除它并尝试更具体。
答案 0 :(得分:1)
我意识到我的代码对其他人来说很方便。我将它放在https://github.com/LadaF/Fortran---CGAL-polyhedra下的GNU GPL v3许可证下。
您可以查询点是否在点内。首先,你通过阅读文件
cgal_polyhedron_read
。您必须存储已装箱的type(c_ptr) :: ptree
并在下次通话中使用它。
函数cgal_polyhedron_inside
返回一个点是否在多面体内部。它需要一个参考点,必须知道它在外面。
完成电话cgal_polyhedron_finalize
。
您必须将文件作为OFF文件中的纯三对角流形网格。您可以使用http://www.cs.princeton.edu/~min/meshconv/从STL文件创建它。