포트란에 포인트가있는 STL 파일을 채우려고합니다. 기본 코드를 작성했지만 작동하지 않습니다.포트란 - STL의 포인트
내 방법은 난수 생성기를 사용하여 점을 생성하는 것이 었습니다. 그런 다음이 점을 STL 경계 상자의 크기로 표준화합니다.
그런 다음 STL의 첫 번째 삼각형에 대해 "z"좌표를 내 보냅니다. 임의의 점이 첫 번째 삼각형의 "x"와 "y"좌표의 최대 값과 최소값인지 확인합니다. 그렇다면 나는 임의의 점을 삼각형 평면에 수직으로 투영하고 평면과 교차해야하는 "z"값을 계산합니다. 그런 다음 임의의 점의 z 값이 투영 된 점의 값보다 작은 지 확인합니다 (레이 캐스팅). 그렇다면 처음에 0으로 설정된 카운터를 1 씩 증가시킵니다.
STL의 모든 삼각형에 대해 이렇게합니다. 카운터가 무작위 포인트라도 볼륨 밖에 있으면, 홀수 인 경우 무작위 포인트가 볼륨 안에 있고 포인트가 저장됩니다.
그런 다음 새로운 임의의 점을 생성하고 다시 시작합니다. 나는 아래에 중요한 코드를 포함시켰다. 길이에 대한 사과 (많은 댓글과 가독성을위한 빈 줄). 테스트 STL 파일 (here에서 가져온 배) -
! 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 파일을 읽고 각 삼각형의 표면 법선과이 삼각형을 구성하는 정점을 저장합니다. 그런 다음 정점을 텍스트 파일에 쓰고 위 그림과 같이 각 삼각형의 정점을 연결하는 GNUPLOT을 호출합니다. 이 플롯은 STL 파일을 올바르게 읽고 저장하는 테스트입니다. 표면 법선을 사용하지 않습니다. . 이미지 2 - 이것은 STL 볼륨 내부에있는 것으로 받아 들여진 후보 포인트의 플롯입니다. (위의 코드에 표시된 마지막 if 루프에 저장 됨). 이 허용 된 점은 나중에 텍스트 파일에 쓰여지고 GNUPLOT (NOT SHOWN)으로 그려집니다. 알고리즘이 작동했다면이 플롯은 위에 표시된 삼각형 메쉬의 점 구름이어야합니다. (또한 랜덤 파티클이 올바른 범위에서 생성되도록 8 경계 상자 좌표를 표시합니다.)
평행선을 실행하거나 가장자리와 교차하는 광선에 대해 생성 된 점을 고려하지 않은 점을 높이 평가합니다. 난 그냥 거친 코드로 시작하고 싶었어. 내 방법론이나 코드에 문제가 있다면 조언 해 주실 수 있습니까? 질문이 너무 광범위하다면 알려주고 삭제하겠습니다.
이미지에 댓글을 달 수 있습니까?그들이 보여주는 것> 두 코드 모두 결과입니까? –
@VladimirF, 위의 이미지에 몇 가지 설명을 추가했습니다. 요약하면 Image 1은 프로그램에 의해 읽혀지고 올바른 저장을 보장하기 위해 그려진 일반적인 삼각 메쉬입니다. 이미지 2는 점으로 채워진 동일한 볼륨의 플롯을 나타냅니다 (위의 코드를 사용하여 테스트되었고 삼각형 화 된 메쉬 내부에있는 임의의 점). – 1QuickQuestion
그래서 당신이 필요로하는 것은 점이 비 convex 다면체 안에 있는지 확인하는 것입니다. 나는 그것을 위해 도서관을 사용할 것이다. 나는 OFF 파일을 읽으려고 CGAL을 사용하지만 내부로 또는 직접적으로 리턴하지는 않는다. 그래서 나는 레이와의 교차 수를 세어야한다. http://gts.sourceforge.net/은 어떻습니까? –