Post Lists

2018년 12월 10일 월요일

원통Cylinder(or 원뿔cone) 렌더링하기

http://paulbourke.net/geometry/circlesphere/

다음은 어떻게 "이상적인" cylinder (or cone)을 discrete facets들로 나타내는지를 설명한다. 이것을 하길 원하는 이유들은 대개 cylinder primitive를 지원하지 않는 환경, 예를들어 OpenGL, DXF 그리고 STL같은 환경으로부터 기인한다. cylinder의 매우 일반적인 정의가 사용될 것인데, 그것은 두 개의 끝점과 각 끝에서의 한 반지름으로 정의될 것이다. 전통적인 cylinder는 두 개의 반지름이 같을 것이고, tapered cylinder는 다른 반지름을 가질 것이고, cone은 한 끝에서 zero 반지름을 가질 것이다.

다음의 이미지는 4개의 vertex faces 또는 전체 3개의 vertex facets가 있는 cylinder들을 보여준다. 4 vertex polygons는 coplanar이기 때문에, 그것들을 두 개의 3 vertex facets로 분리하는 것은 resolution을 개선시키지 않는다는 것에 주목해라. End caps는 일반적으로 optional인데, 그것들이 필요하든지 말든지는 프로그램 의존적이다.

facets의 정점들을 명시하기 위해서, cylinder를 구성하는 것은 처음에 cylinder의 축에 수직하고, 서로에 수직인 두 개의 벡터를 필요로한다. 이러한 것들은 오른쪽 그림에서 빨간색과 파란색으로 보여진다. 이러한 두 개의 벡터들을 만드는 많은 방법들이 있는데, 그것들은 보통 cylinder axis와 collinear하지 않는 어떤 벡터의 형태를 요구한다. cylinder axis(P2 - P1)와 함꼐 그 벡터의 외적은 그 벡터들 중 하나를 주고 (가령 A), 그리고 그 축과 함꼐 이 새로운 벡터의 외적은 다른 벡터를 준다 (B). 이러한 두 게의 수직인 벡터들은 그러고나서 표준화된다.

두 개의 수직인 벡터들 A와 b가 주어진다면, cylinder의 rim(테, 가장자리) 주변을 둘러싸는 정점들을 만들 수 있다. 그래서, 4개의 vertex facet에 대해, 그 정점들은 다음에 의해서 주어질지도 모른다, 거기에서 theta2 - theta - 1은 어떤 적절히 작은 각인데, 근사의 roughness를 결정한다.



P1, P2, A, B가 3차원에 있는 모든 벡터이다. r1과 r2는 양 쪽 끝의 반지름이다.

어떤 슈도 c코드로 쓰여진다면, 그 facets들은 다음처럼 만들어질지도 모른다


create A and B
for (i = 0; i < NFACETS; i ++)
{
      n = 0;
      theta1 = i * TWOPI / N;
      theta2 = (i+1) * TWOPI / N;
      q[n].x = P1.x + r1 * cos(theta1) * A.x + r1 * sin(theta1) * B.x
      q[n].y = P1.y + r1 * cos(theta1) * A.y + r1 * sin(theta1) * B.y
      q[n].z = P1.z + r1 * cos(theta1) * A.z + r1 * sin(theta1) * B.z
      n++;
      q[n].x = P2.x + r2 * cos(theta1) * A.x + r2 * sin(theta1) * B.x
      q[n].y = P2.y + r2 * cos(theta1) * A.y + r2 * sin(theta1) * B.y
      q[n].z = P2.z + r2 * cos(theta1) * A.z + r2 * sin(theta1) * B.z
      n++;
      if (r2 != 0) {
         q[n].x = P2.x + r2 * cos(theta2) * A.x + r2 * sin(theta2) * B.x
         q[n].y = P2.y + r2 * cos(theta2) * A.y + r2 * sin(theta2) * B.y
         q[n].z = P2.z + r2 * cos(theta2) * A.z + r2 * sin(theta2) * B.z
         n++;
      }
      if (r1 != 0) {
         q[n].x = P1.x + r1 * cos(theta2) * A.x + r1 * sin(theta2) * B.x
         q[n].y = P1.y + r1 * cos(theta2) * A.y + r1 * sin(theta2) * B.y
         q[n].z = P1.z + r1 * cos(theta2) * A.z + r1 * sin(theta2) * B.z
         n++;
      }
      do something with q[0..n]
}

Note

  • 여기에 설명된 알고리즘은 음수 반지름도 완벽하게 처리할 것이다. 한 반지름이 음수이고, 다른 것이 양수라면, 그러면 그 cylinder는 단일점을 지나갈 것이고, 효과적으로 두 개의 끝을 가진 cones처럼 보일 것이다. 이것은 항상 허용되지 않는 그것들에서의 twist를 갖는 facets을 이끈다.
  • end caps는 간단히 각 끝에 radius를 체크하도록 하여 형성된다. 만약 그것이 0이 아니라면, 그러면 추가적인 3개의 vertex faces가 정점들 P1, q[0], q[3] 그리고/또는 P2,q[1], q[2]로 만들어진다.
  • 만약 너의 프로그램들이 3개의 정점 facets를 요구한다면, 그러면 위의 4개의 vertex facets은 q[0], q[1], q[2] 그리고 q[0]. q[2]. q[3]이 된다.
  • 너의 프로그램의 어떤 facet orderings requirements에 주의해라. 바깥으로 가리키는 normals를 제외하고 많은 패키지들에서, 정점들의 정확한 순서는 또한 너가 왼손 또는 오른손 좌표계를 쓰는지에 의존한다.


댓글 없음:

댓글 쓰기