1. Ruby-LibGD 환경 구성 및 초기화
이 데모의 핵심은 gd 라이브러리를 Ruby 환경에서 호출하여 사용하는 것입니다. GD::Image.new를 통해 900x900 크기의 캔버스를 생성하며, 가능한 경우 트루컬러(Truecolor) 모드를 사용하여 풍부한 색상 표현을 지원합니다. 트루컬러 지원 여부에 따라 예외 처리를 수행하여 안정성을 확보하였으며, 배경색을 어두운 톤(RGB 14, 14, 18)으로 설정하여 렌더링될 객체가 돋보이도록 구성했습니다.
2. 수학적 헬퍼 함수 및 3D 변환
3차원 객체를 구현하기 위해 다양한 수학적 함수가 정의되었습니다.
- 색상 변환:
hsv_to_rgb함수는 0.0에서 1.0 사이의 색상(Hue), 채도(Saturation), 명도(Value)를 RGB 값으로 변환합니다. 이를 통해 도넛 표면에 무지개색 효과를 부여합니다. - 회전 행렬:
rot_x,rot_y,rot_z함수는 삼각함수(Math.cos, Math.sin)를 사용하여 3차원 공간상의 점을 특정 축을 기준으로 회전시킵니다. 이는 객체의 입체적인 각도를 조절하는 데 필수적입니다. - 픽셀 제어:
set_px함수는 라이브러리의 메서드 지원 여부에 따라set_pixel,pixel, 또는[]=를 선택적으로 호출하여 유연한 픽셀 쓰기 기능을 제공합니다.
3. 토러스(Torus) 기하학 모델링
도넛 모양을 만들기 위해 매개변수 방정식을 사용합니다. 주요 반지름(R)과 보조 반지름(r)을 설정하고, 두 개의 루프를 통해 표면의 점들을 샘플링합니다.
u와v각도를 0부터 2π까지 변화시키며 토러스 표면의 x, y, z 좌표를 계산합니다.- 계산된 좌표에 회전 파라미터(
ax,ay,az)를 적용하여 입체적인 배치를 완료합니다. - 표면의 법선 벡터(Normal)를 함께 계산하여 이후 조명 효과 계산에 활용합니다.
4. 원근 투영 및 조명 효과
계산된 3D 좌표를 2D 화면에 투영하기 위해 원근법(Perspective)을 적용합니다. fov와 z_offset 파라미터를 사용하여 멀리 있는 점은 작게, 가까이 있는 점은 크게 보이도록 스케일을 조정합니다.
조명 효과는 람베르트 반사(Lambertian Reflection) 모델을 기반으로 합니다. 광원 벡터와 표면 법선 벡터의 내적(ndotl)을 구하여 밝기를 결정하며, 여기에 거듭제곱을 활용한 스펙큘러 하이라이트를 추가하여 금속성이나 광택이 나는 질감을 표현합니다.
5. 화가 알고리즘을 통한 렌더링 및 출력
3차원 객체의 겹침 문제를 해결하기 위해 ‘화가 알고리즘(Painter’s Algorithm)’을 사용합니다. 모든 점의 데이터를 points 배열에 저장한 뒤, 깊이 값(zc)을 기준으로 정렬합니다. 이후 먼 곳에 있는 점부터 순차적으로 캔버스에 그림으로써 앞뒤 관계가 올바르게 표현되도록 합니다.
최종적으로 각 점은 2x2 픽셀 크기의 점(dot)으로 그려지며, img.png 또는 img.save 메서드를 통해 donut_3d.png 파일로 저장됩니다. 이 과정에서 색상 캐싱을 통해 중복되는 GD::Color 객체 생성을 방지하여 성능을 최적화했습니다.