쿼터니언을 오일러각으로 변환 > IT Tip&Tech

본문 바로가기
사이트 내 전체검색


회원로그인

IT Tip&Tech

쿼터니언을 오일러각으로 변환

페이지 정보

작성자 black_H 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 작성일18-03-03 16:19 조회438회 댓글2건

본문

쿼터니언(사원수) 회전이 짐벌락이 없고 매우 효율적인건 분명하나 

모든 프로그래머가 쿼터니언을 수학적인 이해를 바탕으로 사용하는건 아닙니다.

 특히나 일반적인 상황에서는 오일러 방식이 이해하기 단순합니다. 

 

그래서 내부적으로는 쿼터니언을 쓰고 외부에서는 오일러 개념으로만 운용하는 클래스를 만들어 보고 싶었습니다.

 

언리얼 엔진에서 차용하는 방식인데 Rotator 클래스에서 Yaw, Pitch, Roll 로 제어를 하지만 

내부에서는 쿼터니언을 사용해서 계산합니다. 

 

그리고 그렇게 계산된 Rotation을 언제고 Yaw, Pitch, Roll 오일러 각으로 분해하는것을 보고 

저도 해보고 싶어서 쿼터니언을 오일러각으로 변환하고 싶었습니다만...

 

당췌 키워드를 뭘 찾아야 할지도 모르겠고 의외로 관심이 없어서 놀랐습니다...

둘중 하나인거 같은데 

 

1. 당연한걸 왜 굳이...

2. 나만 못찾는거..

 

여튼 거의 하루종일 찾은거 같습니다. 

답은 찾았는데 왜 이렇게 돌아가는지는 잘 모르겠습니다....

 

여튼 한 유저가 찾은 방법이고 착안은 유니티에서 .ToEuler() 펑션에서 한것으로알고 있습니다.

 

 public static Quaternion ToQ (Vector3 v)

{

    return ToQ (v.y, v.x, v.z);

}

 

public static Quaternion ToQ (float yaw, float pitch, float roll)

{

    yaw *= Mathf.Deg2Rad;

    pitch *= Mathf.Deg2Rad;

    roll *= Mathf.Deg2Rad;

    float rollOver2 = roll * 0.5f;

    float sinRollOver2 = (float)Math.Sin ((double)rollOver2);

    float cosRollOver2 = (float)Math.Cos ((double)rollOver2);

    float pitchOver2 = pitch * 0.5f;

    float sinPitchOver2 = (float)Math.Sin ((double)pitchOver2);

    float cosPitchOver2 = (float)Math.Cos ((double)pitchOver2);

    float yawOver2 = yaw * 0.5f;

    float sinYawOver2 = (float)Math.Sin ((double)yawOver2);

    float cosYawOver2 = (float)Math.Cos ((double)yawOver2);

    Quaternion result;

    result.w = cosYawOver2 * cosPitchOver2 * cosRollOver2 + sinYawOver2 * sinPitchOver2 * sinRollOver2;

    result.x = cosYawOver2 * sinPitchOver2 * cosRollOver2 + sinYawOver2 * cosPitchOver2 * sinRollOver2;

    result.y = sinYawOver2 * cosPitchOver2 * cosRollOver2 - cosYawOver2 * sinPitchOver2 * sinRollOver2;

    result.z = cosYawOver2 * cosPitchOver2 * sinRollOver2 - sinYawOver2 * sinPitchOver2 * cosRollOver2;

 

    return result;

}

 

public static Vector3 FromQ2 (Quaternion q1)

{

    float sqw = q1.w * q1.w;

    float sqx = q1.x * q1.x;

    float sqy = q1.y * q1.y;

    float sqz = q1.z * q1.z;

    float unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor

    float test = q1.x * q1.w - q1.y * q1.z;

    Vector3 v;

 

    if (test>0.4995f*unit) { // singularity at north pole

        v.y = 2f * Mathf.Atan2 (q1.y, q1.x);

        v.x = Mathf.PI / 2;

        v.z = 0;

        return NormalizeAngles (v * Mathf.Rad2Deg);

    }

    if (test<-0.4995f*unit) { // singularity at south pole

        v.y = -2f * Mathf.Atan2 (q1.y, q1.x);

        v.x = -Mathf.PI / 2;

        v.z = 0;

        return NormalizeAngles (v * Mathf.Rad2Deg);

    }

    Quaternion q = new Quaternion (q1.w, q1.z, q1.x, q1.y);

    v.y = (float)Math.Atan2 (2f * q.x * q.w + 2f * q.y * q.z, 1 - 2f * (q.z * q.z + q.w * q.w));     // Yaw

    v.x = (float)Math.Asin (2f * (q.x * q.z - q.w * q.y));                             // Pitch

    v.z = (float)Math.Atan2 (2f * q.x * q.y + 2f * q.z * q.w, 1 - 2f * (q.y * q.y + q.z * q.z));      // Roll

    return NormalizeAngles (v * Mathf.Rad2Deg);

}

 

static Vector3 NormalizeAngles (Vector3 angles)

{

    angles.x = NormalizeAngle (angles.x);

    angles.y = NormalizeAngle (angles.y);

    angles.z = NormalizeAngle (angles.z);

    return angles;

}

 

static float NormalizeAngle (float angle)

{

    while (angle>360)

        angle -= 360;

    while (angle<0)

        angle += 360;

    return angle;

}

 

 

여기서 봐야할건 FromQ 이고요.

FromQ함수에서 변환할때 주의점은 쿼터니언은 기본적으로 360를 표현하지 못한다 합니다.

180기준으로 판별할수 밖에 없어서 180도가 넘어가는 경우 마이너스 각도로 판별하는것 까진 알겠는데..

 

왜 쿼터니언의 xyzw 를 뒤집에서 계산하는지는 제 수학력의 한계입니다.

 

어쨌든 다행히도 몇개의 각을 테스트 해보고 조합해서 결과값을 뽑아보니 아주 훌륭하게 오일러 각으로 잘 변환했습니다. 

 

하... 왜 이거 한국문서나 영어문서 전부 이렇게 찾기 힘들었던 걸까요...

 

찾고나니 좀 허무해졌습니다. 

 

  • 페이스북으로 보내기
  • 트위터로 보내기
  • 구글플러스로 보내기

댓글목록

책읽는아이님의 댓글

책읽는아이 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 작성일

요즘 잘 안 찾아지는건 트랜드가 지나버렸기 때문이겠죠..

다렉 9.x 사용해 개발하던 시절만 해도 직접 바닥부터 개발하거나 미들웨어 정도의 라이브러리를 가져다가 조합해서 자체 엔진을 구성하던 환경이라 본문의 내용이 많은 관심을 받는 주요 기술이었죠.

감자님 (이성수님? 맞나..;;;;;) 블로그도 많이 핫했었고요..
근데 이제는 유니티나 언리얼 같은 엔진이 대부분 커버해버리다 보니 개략적인 개념만 알고 지나가는게 아닌가 하는 생각이 듭니다.

7,8 년 전 쯤만해도 검색하면 어렵지 않게 검색 결과에 노출되던 내용들인 거로 기억합니당.. 'ㅅ'a

IT Tip&Tech 목록

Total 121건 1 페이지
IT Tip&Tech 목록
번호 제목 글쓴이 날짜 조회
121 마소가 Azure Sphere 라는걸 만들었데요. 책읽는아이 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 04-17 169
120 MTPutty 댓글1 책읽는아이 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 04-16 182
119 Visual Studio 툴바 아이콘들 사라질때 해결방법 첨부파일 black_H 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 04-13 203
118 openvpn 연결 후 1시간뒤 연결이 자동으로 끊긴다면 책읽는아이 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 04-04 213
117 openvpn ip 고정시키기 책읽는아이 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 04-03 253
116 openvpn id/pwd 로 접속하기 책읽는아이 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 04-02 228
115 openvpn 설치해보기 댓글1 책읽는아이 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 04-02 242
114 Pro Git 이 무료로 배포되고 있었군요. 댓글1 책읽는아이 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 03-20 324
113 비쥬얼 스튜디오 외부 라이브러리 추가하기 black_H 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 03-16 332
112 아두이노의 인터럽트 댓글2 책읽는아이 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 03-13 378
111 라즈비안에 문라이트 세팅하기 (2018.3) 댓글2 black_H 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 03-13 438
110 Memory as a Programming Concept in C and C++ 댓글3 책읽는아이 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 03-12 391
열람중 쿼터니언을 오일러각으로 변환 댓글2 관련링크 black_H 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 03-03 439
108 4K Video Downloader 댓글1 책읽는아이 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 02-21 438
107 VS Code + Go : 환경변수 GOROOT 과 GOPATH 책읽는아이 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 12-28 607
게시물 검색

접속자집계

오늘
623
어제
659
최대
3,675
전체
362,621
회사소개 개인정보취급방침 서비스이용약관
Copyright © LittleCandle All rights reserved.
문의메일 : littlecandle99@gmail.com
상단으로
모바일 버전으로 보기