【发布时间】:2014-09-18 21:12:34
【问题描述】:
我正在尝试用 Fortran 中的点填充 STL 文件。我已经编写了一个基本代码,但它不起作用。
我的方法是使用随机数生成器来生成一个点。然后我将此点标准化为 STL 边界框的尺寸。
然后我抛出 STL 中第一个三角形的“z”坐标。我检查随机点是否具有第一个三角形的“x”和“y”坐标的最大值和最小值。如果是这样,我将随机点垂直投影到三角形平面上,并计算它与平面相交的“z”值。然后我检查随机点的 z 值是否小于投影点的值(射线投射)。如果是,我将最初设置为零的计数器加一。
我对 STL 中的每个三角形都这样做。如果计数器是偶数则随机点在体积外,如果是奇数则随机点在体积内并存储。
然后我生成一个新的随机点并重新开始。我在下面包含了重要的代码。为篇幅道歉(为了便于阅读,有很多 cmets 和空行)。
! 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 个边界框坐标,以确保随机粒子生成在正确的范围内)
我明白这没有考虑在顶点或射线上生成的点,这些点平行运行并与边缘相交。我只是想从一个粗略的代码开始。您能否告知我的方法或代码是否有问题?如果问题太宽泛,请告诉我,我将删除它并尝试更具体。
【问题讨论】:
-
你能评论这些图片吗?它们显示了什么>都是你的代码的结果吗?
-
@VladimirF ,我在上面的图片中添加了一些 cmets。简而言之 - 图 1 是一个通用的三角网格,它已被程序读入,然后绘制以确保正确存储。图 2 旨在绘制由点填充的相同体积的图(即使用上述代码测试并发现位于三角网格内的随机点)。
-
那么你需要检查一个点是否在非凸多面体内?我会为此使用图书馆。我使用 CGAL 读取 OFF 文件,但它不直接返回内部或不直接返回,然后我必须计算与射线相交的数量。 gts.sourceforge.net 呢?
-
@VladimirF 是的,我正在尝试检查一个点是否在非凸三维多面体内。我对编码和 Fortran 很陌生(以前从未使用过库)而且我不知道任何 C++。我会看一下 GTS 库,看看有没有什么我可以使用的。
-
但是仍然可以在这里询问算法,但要知道这并不容易。
标签: fortran raycasting particles