성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] Detecting blocking calls using asyn...
[정성태] 아쉽게도, 커뮤니티는 아니고 개인 블로그입니다. ^^
[정성태] 질문이 잘 이해가 안 됩니다. 우선, 해당 소스코드에서 ILis...
[양승조
] var대신 dinamic으로 선언해서 해결은 했습니다. 맞는 해...
[양승조
] 또 막혔습니다. ㅠㅠ var list = props[i].Ge...
[양승조
] 아. 감사합니다. 어제는 안됐던것 같은데....정신을 차려야겠네...
[정성태] "props[i].GetValue(props[i])" 코드에서 ...
[정성태] 저렇게 조각 코드 말고, 실제로 재현이 되는 예제 프로젝트를 압...
[정성태] Modules 창(Ctrl+Shift+U)을 띄워서, 해당 Op...
[정성태] 만드실 수 있습니다. 단지, Unity 엔진 내의 스크립트와 W...
글쓰기
제목
이름
암호
전자우편
HTML
홈페이지
유형
제니퍼 .NET
닷넷
COM 개체 관련
스크립트
VC++
VS.NET IDE
Windows
Team Foundation Server
디버깅 기술
오류 유형
개발 환경 구성
웹
기타
Linux
Java
DDK
Math
Phone
Graphics
사물인터넷
부모글 보이기/감추기
내용
<div style='display: inline'> <h1 style='font-family: Malgun Gothic, Consolas; font-size: 20pt; color: #006699; text-align: center; font-weight: bold'>3D 공간에서 두 점이 이루는 각도 구하기</h1> <p> 예를 들어, 다음과 같이 3D 공간에서 면과 점이 있다고 가정해 보겠습니다.<br /> <br /> <img alt='angle_between_two_0.png' src='/SysWebRes/bbs/angle_between_two_0.png' /><br /> (오른손 좌표계 시스템의 x-y-z 축을 사용하고 있습니다.)<br /> <br /> 이때 점 C와 점 A가 이루는 각도는 어떻게 될까요? 간단하게 점과 점의 위치를 빼서 벡터를 만들고,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 점 C와 카메라의 벡터 = 점 C - 점 A = (-1.4, -2.9, -5) </pre> <br /> 그 벡터가 이루는 각을 3차원에 따라 각 축 별로 3개의 각도를 구할 수 있습니다.<br /> <br /> <ul> <li>x-축을 기준으로 y-z 평면의 각</li> <li>y-축을 기준으로 x-z 평면의 각</li> <li>z-축을 기준으로 x-y 평면의 각</li> </ul> <br /> 역시 시각화를 해보는 게 좋겠지요? ^^ GeoGebra 앱에서 "Home" 모양의 아이콘을 누르면,<br /> <br /> <img alt='angle_between_two_1.png' src='/SysWebRes/bbs/angle_between_two_1.png' /><br /> <br /> 차례대로 "y축을 기준으로 x-z 평면", "z축을 기준으로 x-y 평면", "x축을 기준으로 y-z 평면" 상에서의 물체를 볼 수 있는 기능이 제공됩니다.<br /> <br /> 자... 멋진 툴이 있으니, 그럼 우선 첫 번째 아이콘인 "y축을 기준으로 x-z 평면"을 다음과 같이 볼 수 있습니다. ^^<br /> <br /> <img alt='angle_between_two_2_y.png' src='/SysWebRes/bbs/angle_between_two_2_y.png' /><br /> <br /> 보는 바와 같이 x-z 평면에서 벡터가 이루는 각을 쉽게 확인할 수 있습니다. 점 A에서 x-축으로 수선의 발을 그렸을 때, <br /> <br /> <img alt='angle_between_two_3.png' src='/SysWebRes/bbs/angle_between_two_3.png' /><br /> <br /> 직각 삼각형이 되고 이때 우리가 아는 벡터 A의 x, z 성분의 값으로 인해 아크 탄젠트 함수를 사용하면 점 A에서 이루는 각도를 구할 수 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 각 A = arc_tangent(v<sub>x</sub>, v<sub>z</sub>); </pre> <br /> C# 코드로 구해 보면 다음과 같습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Vector3 v3 = new Vector3(-1.4f, -2.9f, -5f); { double yAngle = Math.Atan2(v3.X, v3.Z); Console.WriteLine(RadianToDegree(yAngle)); } </pre> <br /> 실행해 보면, -164.357753796137도가 나오는데, 벡터가 음의 방향이어서 그런 것일 뿐 180도를 빼면 약 15.6도가 나옵니다. 동일한 각도를 Geogebra 기하를 이용해서도 구해 볼까요? ^^<br /> <br /> 2차원 좌표계에서 x, z의 성분으로 점을 표시한 후 그와 연결한 벡터를 그리고 그 <a target='tab' href='http://www.sysnet.pe.kr/2/0/11569'>사잇각</a>을 다음과 같이 구할 수 있습니다.<br /> <br /> <img alt='angle_between_two_4.png' src='/SysWebRes/bbs/angle_between_two_4.png' /><br /> <br /> 잘 맞아 들어가는군요. ^^<br /> <br /> <hr style='width: 50%' /><br /> <br /> 마찬가지 방식으로 "z축을 기준으로 x-y 평면"과,<br /> <br /> <img alt='angle_between_two_2_z.png' src='/SysWebRes/bbs/angle_between_two_2_z.png' /><br /> <br /> "x축을 기준으로 y-z 평면" 상의 모습을 확인하며,<br /> <br /> <img alt='angle_between_two_2_x.png' src='/SysWebRes/bbs/angle_between_two_2_x.png' /><br /> <br /> 각도를 구해 보면 이렇습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Vector3 v3 = new Vector3(-1.4f, -2.9f, -5f); Console.WriteLine("xAngle"); { double xAngle = Math.Atan2(v3.Y, v3.Z); Console.WriteLine(RadianToDegree(xAngle)); } Console.WriteLine("yAngle"); { double yAngle = Math.Atan2(v3.X, v3.Z); Console.WriteLine(RadianToDegree(yAngle)); } Console.WriteLine("zAngle"); { double zAngle = Math.Atan2(v3.Y, v3.X); Console.WriteLine(RadianToDegree(zAngle)); } /* 출력 결과 xAngle -149.886266031276 yAngle -164.357753796137 zAngle -115.769326504636 */ </pre> <br /> (<a target='tab' href='http://www.sysnet.pe.kr/bbs/DownloadAttachment.aspx?fid=1325&boardid=331301885'>첨부 파일은 이 글에서 예제로 사용한 geogebra 파일</a>입니다.)<br /> <br /> <hr style='width: 50%' /><br /> <br /> 참고로, 2개의 벡터가 이루는 각은 아크코사인을 이용해 구할 수 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > vector v1 = ...; vector v2 = ...; vector nv1 = normalize(v1); vector nv2 = normalize(v2); float angle = acos(mul(nv1, nv2)); </pre> <br /> 일반적으로 acos의 정의역이 -1 ~ 1이기 때문에 정규화된 벡터의 내적 연산으로 NaN 값을 반환하는 경우는 없습니다. 문제는 0 벡터인 경우 normalize 하는 과정에서 NaN이 나온다는 것입니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > vector v = vector(0, 0, 0, 0); vector normal = normalize(v); // normal == NaN </pre> <br /> 왜냐하면 정규화라는 것이 벡터 크기로 나누는 것인데,<br /> <br /> ${<br /> \hat v = \left ( \frac{ v_x }{ \Vert v \Vert }, \frac{ v_y }{ \Vert v \Vert }, \frac{ v_z }{ \Vert v \Vert } \right )<br /> }$<br /> <br /> 분모가 0이 되므로 normalize의 결과가 NaN이 나옵니다. 이 때문에 mul 연산도 NaN이 되고, acos까지 NaN으로 끝납니다.<br /> </p><br /> <br /><hr /><span style='color: Maroon'>[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
6526
(왼쪽의 숫자를 입력해야 합니다.)