*좌표계

좌표계를 표현하는 방식으론

서로 직교하는 두 축과 두 축의 교첨인 원점으로 나타낸다.

가로축을 X축, 세로축을 Y축이라 칭하고 교점을 O라 표기한다.

이는 데카르트 좌표계로 "직교좌표계", "cartesian좌표계"라 칭하기도 한다.

 

임의 점 P를 표현하는 방법은 점P에서 수선의 발을 내렸을 때

X축과 직교하는 지점이 좌표x값

Y축과 직교하는 지점이 좌표y값 이다.

 

원점부터 임의 점 P까지의 위치를 구하는 방법으론 피타고라스의 정리를 이용할 수 있다.

x를 가로의 길이, y를 세로의 길이로 놓았을때 원점부터 점P까지의 거리는 빗변 a의 길이가 된다.

a^2 = x^2 + y^2

 

*삼각비

삼각비는 직각삼각형에서 세 변중 두 변의 길이의 비율을 나타낸다.

두 변사이에 끼인각 θ에 대해

 

cosθ = 밑변 / 빗변 = c / a

sinθ = 높이 / 빗변 = b / a

tanθ = 높이 / 밑변 = b / a

 

cosθ를 예로 들어

cosθ = c / a 는 cosθ * a = c x 1로 표기 할 수 있다.

비례식으로 나타내면

a : c = 1 : cosθ 가 된다.

이는 a를 100%라 놓았을 때 c는 a에 대해 cosθ만큼의 비율을 가진다.

 

*내적

-각도

내적은 여러 기하학적 의미를 표현 할 수 있는데

그중 하나는 두 단위 방향벡터 사이의 각을 구할 때 쓰인다.

 

먼저 A, B 두 방향벡터가 있을때 내적 공식을 보면

A ο B = ||A|| * ||B|| * cosθ 이다.

 

두 선분 사이의 끼인각은 선분의 길이의 영향을 받지 않으므로

A, B의 단위벡터인 A", B"을 내적하면

A" ο B" = 1 * 1 * cosθ

A" ο B" = cosθ 가 성립 된다.

 

위 식 양변에 역코사인을 취해주면

acos( A' ο B' ) = acos( cosθ )

acos( A' ο B' ) = θ

결론적으로 각도(radian)만 남게된다.

 

-정사영

또 하나는 두 방향벡터 A, B가 있을때 B벡터에 대한 A벡터의 정사영을 구할 수 있다.

공식을 다시 보면

A ο B = ||A|| * ||B|| * cosθ 이다.

이때 B벡터를 정규화 시킨 B" 과의 내적연산을 하면

A ο B" = ||A|| * 1 * cosθ 식이 나온다

이때 A ο B" 은 A벡터 머리에서 B벡터로 수선의 발을 내린 즉 정사영의 길이를 나타낸다.

B" 에 내적연산의 값을 곱해주게되면 수선의 발을 내려 B와 교차하는 지점의 좌표를 알 수 있다.

 

두 벡터 A, B

수선의 발 N

정사영 S

 

A = 파랑

B = 빨강

N = 하양

S = 검정

 

'programming > etc' 카테고리의 다른 글

쿼드트리 ( QuadTree )  (0) 2024.07.26
OBB 충돌  (0) 2024.07.26
카메라  (0) 2024.07.26
렌더링 파이프 라인  (0) 2024.07.26
평면방정식  (0) 2024.07.26
Posted by mainep
:

picking

programming/direct3d 2024. 7. 26. 10:23 |

 

 

우선 winProcedure 콜백함수에서 마우스 좌료를 얻는다

또는 API함수인 GetCursorPos함수로 window상 좌표를 받아오고

ScreenToClient함수를 사용해 Client좌표로 변형 시켜줄 수 있다.

전자는 client영역에 마우스포인터가 존재해야 좌표를 갱신하고

후자는 window상의 좌표를 변형시켜준거라 client영역을 벗어나도 좌표가 갱신된다.

 

-

 

받아온 client상의 좌표를 direct3d좌표계로 변형시켜줘야한다. 범위[ -1, 1 ]

direct3D는 왼손 좌표계를 사용한다.

 

여기서 y값을 보면 client는 좌상단을 원점으로 아래로 내려갈수록 y값이 증가하게된다.

때문에 상,하를 반전시켜주어야 한다.

 

convPos.x = 2.f * clientPos.x / backBufferWidth - 1.f

convPos.y = 1.f - 2.f * clientPos.y / backBufferHeight

convPos.z = 1.f

 

좌표계 변환도 해주었으니 이제 뷰 공간으로 변형시켜줘야한다.

IDirect3DDevice9::GetTransform() 함수를 이용하여 projection행렬을 얻어온다.

convPos.x /= matProj._11

convPos.y /= matProj._22

 

이는 d3d좌표계로 변환된 정점에 projection행렬의 역행렬을 곱해준것과 같다.

 

-

 

IDirect3DDevice9::GetTransform() 함수를 이용하여 view행렬을 얻어온다.

D3DXMatrixInverse() 함수를 이용하여 view의 역행렬을 구하면

현재 카메라의 회전행렬과 카메라의 위치를 구할수있다.

 

-

 

먼저 카메라의 위치에서 월드 공간상 마우스포인터의 위치로 향하는 방향백터를 구하기위해

D3DXVec3TransformNomal() 함수를 이용하여 matInverseView행렬을 곱해준다.

이 함수는 3차원벡터를 1x4행렬로 변환후 w원소에 0을 넣어 행렬x행렬 연산을 해준다.

이로서 월드공간상의 vPickDir을 구할 수 있다.

 

-

 

matInverseView행렬의 (4,1), (4,2), (4,3) 원소는 camera의 현재 위치를 나타낸다.

 

가공해 얻어낸 정보

- vPickDir

- vCameraPos

 

*IntersectTriangle() 분석

http://jebi.tistory.com/377

IntersectTriangle 분석

A. 기본 원리 i) 두 벡터로 만들 수 있는 삼각형 OAB가 있다. ii) 이 삼각형의 두 벡터 OA와 OB는 스칼라 u와 v에 의해 다음과 같은 벡터를 얻을 수 있다. Oa = u * OA Ob = v * OB iii) OA와 OB 사이를 지내는 벡터 OP가 있다고 하자. iv) 이 벡터 OP는 두 벡터 Oa와 Ob의 합으로 나타낼 수 있다 OP = u*OA + u*OB u와 v의 합이 1보다 작거나 같은 경우 u가 1이고, v가 0인 경우 u와 v가 각각 0.5인 경우 u가 0이고, v가 1..

jebi.tistory.com

 

 

 

Posted by mainep
:

카메라

programming/etc 2024. 7. 26. 10:22 |

 

*카메라

양의 z축을 바라보는 벡터를 기준으로 회전 행렬을 만들어준다.

회전시킨곳은 카메라의 방향벡터가 되고

회전행렬의 (3,1), (3,2), (3,3) 원소는 각 xyz의 값으로 좌표를 얻어낼 수 있다.

얻어낸 좌표는 방향벡터이므로 방향벡터에 -1을 곱하여 반전시켜준다.

이는 카메라의 위치가 된다.

카메라의 위치를 회전행렬의 위치성분을 나타내는 (4,1), (4,2), (4,3)에 넣어주고

카메라의 타겟이 될 대상의 이동행렬과 곱해준다 ( rotateMatrix * translationMatrix )

새로 얻어낸 행렬은 뷰 행렬의 역행렬이 되고 이행렬의 역행렬을 다시 구해주면 view행렬이 완성된다.

 

*회전행렬의 (3,1), (3,2), (3,3)

x축을 기준으로 @만큼 회전시킨 행렬의 3행성분과 y축을 기준으로 #만큼 회전시킨 행렬과의 연산된 값으로

x = (3,1) = sin@ * cos#

y = (3,2) = -cos@

z = (3,3) = sin@ * sin#

값을 가진다.

이 x,y,z성분은 양의 z축을 바라보는 벡터를 회전시킨 방향벡터가 된다.

 

양의 z축( 0.f, 0.f, 1.f )을 바라보는 zup벡터를 1x4행렬로 변환하여 w원소에 0을 넣고

회전행렬 matRo와 행렬x행렬 연산하여 3차원 벡터로 다시 변형 시켜준것과 같다.

 

*X축기준 회전행렬 matRoX

1 0 0 0

 

0 sin@ cos@ 0

 

0 -cos@ sin@ 0

 

0 0 0 1

 

*Y축기준 회전행렬 matRoY

sin@ 0 -cos@ 0

 

0 1 0 0

 

cos@ 0 sin@ 0

 

0 0 0 1

 

*matRoX(@) * matRoY(#) = matRoXY( 최종 회전 행렬 )

sin# 0 -cos# 0

 

 

cos@ sin@ cos@ 0

*cos# *sin#

 

 

sin@ -cos@ sin@ 0

*cos# *sin#

 

 

0 0 0 1

 

(3,1) = sin@ * cos#

(3,2) = -cos@

(3,3) = sin@ * sin#

 

*zup( 0, 0, 1, 0 ) * matRoXY

 

(1,1) = ( 0 * sin# ) + ( 0 * cos@ * cos# ) + ( 1 * sin@ * cos# ) + ( 0 * 0 ) = sin@ * cos#

(1,2) = ( 0 * 0 ) + ( 0 * sin@ ) + ( 1 * -cos@ ) + ( 0 * 0 ) = -cos@

(1,3) = ( 0 * -cos# ) + ( 0 * cos@ * sin# ) + ( 1 * sin@ * sin# ) + ( 0 * 0 )

(1,4) = ( 0 * 0 ) + ( 0 * 0 ) + ( 1 * 0 ) + ( 0 * 1 )

 

*

x = matRoXY(3,1) = ( zup * matRoXY )(1,1)

y = matRoXY(3,2) = ( zup * matRoXY )(1,2)

z = matRoXY(3,3) = ( zup * matRoXY )(1,3)

 

 

D3DXMATRIX matRo, matTrans;

D3DXMATRIX matRoX, matRoY;

D3DXMatrixRotationYawPitchRoll( &matRo, D3DXToRadian( m_fYaw ), D3DXToRadian( m_fPitch ), 0.f );

 

//D3DXMatrixRotationX( &matRoX, D3DXToRadian( m_fPitch ) );

//D3DXMatrixRotationY( &matRoY, D3DXToRadian( m_fYaw ) );

//matRo = matRoX * matRoY;

 

D3DXVECTOR3 vTrans( matRo._31, matRo._32, matRo._33 );

 

vTrans *= -1.f;

 

D3DXVec3Normalize( &vTrans, &vTrans );

 

vTrans *= ( 10.F + GETINST(CMouseMgr)->GetWheel() );

 

matRo._41 = vTrans.x;

matRo._42 = vTrans.y + 1.f;

matRo._43 = vTrans.z;

 

D3DXMatrixTranslation( &matTrans, m_vCurPos.x, m_vCurPos.y, m_vCurPos.z );

 

m_matView = matRo * matTrans;

 

D3DXMatrixInverse( &m_matView, NULL, &m_matView );

 

D3DDEVICE()->SetTransform( D3DTS_VIEW, &m_matView );

 

return &m_matView;

 

'programming > etc' 카테고리의 다른 글

OBB 충돌  (0) 2024.07.26
*좌표계*삼각비*내적-정사영  (0) 2024.07.26
렌더링 파이프 라인  (0) 2024.07.26
평면방정식  (0) 2024.07.26
외적  (0) 2024.07.26
Posted by mainep
: