2009-07-12 3 views
4

저는 13 세부터 3D 그래픽을 코딩하는 방법을 배우고 싶었습니다. 이제 10 년 후, 마침내 나는 그것을 풀 수있는 충분한 수학을 축적했다고 생각합니다.3D 큐브 관점 회전 문제

나는 다양한 튜토리얼을 따라하고,

screenX = (pointX * cameraX)/distance 

로 (동등하고, screenY) screenX을 정의 (플러스 오프셋 및 스케일링.)

내 문제는 거리 변수가 실제로에 의미 것과입니다. 나는 거리가 카메라와 포인트 사이의 z의 차이로 정의 된 것을 보았습니다. 그러나 x와 y는 카메라에서 점까지의 실제 거리에 z와 같은 효과가 있기 때문에 완전히 맞을 수는 없습니다. 실제 거리로 거리를 구현했지만, 결과는 "너무 많은"관점을 가지고있는 것처럼 다소 왜곡 된 관점을 제공합니다.

내 "실제 거리"구현의 라인을 따라했다 : 코드와 주변 재생

distance = new Vector(pointX, pointY, cameraZ - pointZ).magnitude() 

, 내 방정식에 추가 변수를 추가하는 perspectiveCoefficient는 다음과 같이

distance = new Vector(pointX * perspectiveCoefficient, 
    pointY * perspectiveCoefficient, cameraZ - pointZ).magnitude() 

어떤 이유로 든 그것이 저를 넘어서 있습니다. perspectiveCoefficient를 1/sqrt (2)로 설정하는 것이 가장 좋은 결과를 얻는 경향이 있습니다.

내 3D 테스트 큐브는 http://vega.soi.city.ac.uk/~abdv866/3dcubetest/3dtest.svg입니다. (Safari와 FF에서 테스트되었습니다.) perspectiveCoefficient를 묻습니다. 여기서 0은 x/y 거리를 고려하지 않고 원근감을 제공하고 1은 x, y 및 z 거리를 똑같이 고려하는 관점을 제공합니다. 기본값은 1/sqrt (2)입니다. 큐브는 화살표 키를 사용하여 x 및 y에 대해 회전 할 수 있습니다. 관심있는 사람은 관련 코드가 View.js 파일의 update()에 있습니다.

이에 대한 아이디어에 감사드립니다.

+3

+1 잘 쓰여진 질문에 대해서는 매우 멋진 대화식 3D SVG 파일입니다. –

답변

5

일반적으로 투영은이 평면 뒤의 눈 위치에서 Z = 0 평면에서 수행됩니다. 투영 된 점은 선 (Pt, Eye)과 Z = 0 평면의 교차점입니다. (0,0, -eyeDist)에서

screenX = scaling * pointX/(1 + pointZ/eyeDist) 
screenY = scaling * pointY/(1 + pointZ/eyeDist) 

내가 카메라가 (0, 0, 0)에서 여기 가정하고 눈 : 마지막에 당신이 뭔가를 얻을. eyeDist가 무한대가되면 평행 투영법을 얻습니다.