Fortran - STL中的点

时间:2014-09-18 10:13:52

标签: fortran raycasting particles

我正在尝试使用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 

我的结果已完全垃圾(见图片)enter image description here图片1 - 测试STL文件(从here发货)。程序的一部分(代码未显示)读入二进制STL文件并存储每个三角形的表面法线和构成该三角形的顶点。然后我将顶点写入文本文件并调用GNUPLOT来连接每个三角形的顶点,如上所示。此图只是一个测试,以确保正确读取和存储STL文件。它不使用曲面法线。 enter image description here。 图2 - 这是被接受为在STL体积内的候选点的图。 (存储在上面代码中显示的最终if循环中)。然后将这些接受的点写入文本文件并用GNUPLOT(不显示)绘制。如果算法有效,这个图应该是上面显示的三角网格的点云。 (它还绘制了8个边界框坐标,以确保在正确的范围内生成随机粒子)

我理解这并没有考虑在顶点上生成的点或平行并与边相交的光线。我只是想从粗略的代码开始。您能否告诉我的方法或代码是否有问题?如果问题太广泛,请告诉我,我会删除它并尝试更具体。

1 个答案:

答案 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文件创建它。