2014-11-10 3 views
1

나는 질문을하기 전에 : 코드가 Eigen 라이브러리를 사용템플릿 및 매트릭스 변환

  1. 있지만, 문제는 일반적인 회전 행렬은 3 × 3 동안
  2. 이 행렬은 다음과 같습니다 특정 라이브러리에 대한되지 않습니다 그래픽 프로그래밍을위한 4x4 (동일 좌표 사용).

그래서 그것은 비켜 ...는 X, Y 및 Z 축에 대한

회전 행렬은 각각 다음 함수로 계산 될 수로 :

Eigen::Matrix4f rotateX(float angle) { 
    float radianAngle = radians(angle); 
    float Sin = sinf(radianAngle); 
    float Cos = cosf(radianAngle); 

    Eigen::Matrix4f rotationMatrix(Eigen::Matrix4f::Identity()); 

    rotationMatrix(1, 1) = Cos; 
    rotationMatrix(1, 2) = Sin; 
    rotationMatrix(2, 1) = -Sin; 
    rotationMatrix(2, 2) = Cos; 

    return rotationMatrix; 
} 

Eigen::Matrix4f rotateY(float angle) { 
    float radianAngle = radians(angle); 
    float Sin = sinf(radianAngle); 
    float Cos = cosf(radianAngle); 

    Eigen::Matrix4f rotationMatrix(Eigen::Matrix4f::Identity()); 

    rotationMatrix(0, 0) = Cos; 
    rotationMatrix(0, 2) = Sin; 
    rotationMatrix(2, 0) = -Sin; 
    rotationMatrix(2, 2) = Cos; 

    return rotationMatrix; 
} 

Eigen::Matrix4f rotateZ(float angle) { 
    float radianAngle = radians(angle); 
    float Sin = sinf(radianAngle); 
    float Cos = cosf(radianAngle); 

    Eigen::Matrix4f rotationMatrix(Eigen::Matrix4f::Identity()); 

    rotationMatrix(0, 0) = Cos; 
    rotationMatrix(0, 1) = Sin; 
    rotationMatrix(1, 0) = -Sin; 
    rotationMatrix(1, 1) = Cos; 

    return rotationMatrix; 
} 

이러한 함수 매우 유사하다; 보시다시피, 유일한 차이점은 매트릭스를 인덱싱하는 것입니다. 이러한 구현은 glm 헤더에도 있습니다.

런타임 오버 헤드를 추가하지 않고 템플릿을 사용하여 이러한 세 가지 기능을 하나로 표현할 수있는 방법이 있습니까?

코드에 대한 의견은 환영합니다. 이 같은

+0

당신은 아마 당신의 회전에 오른쪽 규칙을 유지하기 위해,'sin' 요소에 대한 반대 표시를 가지고있는 Y 회전 행렬을 계획입니다. 오른쪽 좌표계를 가정하면, 즉. – Peter

+0

@Peter 좋은 지적! 그래도 질문은 템플릿에 관한 것이기 때문에 저는 이것을 이렇게 유지할 것입니다. 변형 이상의 것입니다. –

답변

1

뭔가 :

enum Axis {X, Y, Z}; 

// in C++14 you can just use std::max and std::min instead 
constexpr int mymax(int a, int b) { return a > b ? a : b; } 
constexpr int mymin(int a, int b) { return a < b ? a : b; } 

template <Axis axis> 
Eigen::Matrix4f rotateAxis(float angle) { 
    float radianAngle = radians(angle); 
    float Sin = sinf(radianAngle); 
    float Cos = cosf(radianAngle); 

    Eigen::Matrix4f rotationMatrix(Eigen::Matrix4f::Identity()); 

    constexpr int c1 = mymin((axis + 1) % 3, (axis + 2) % 3); 
    constexpr int c2 = mymax((axis + 1) % 3, (axis + 2) % 3); 

    rotationMatrix(c1, c1) = Cos; 
    rotationMatrix(c1, c2) = Sin; 
    rotationMatrix(c2, c1) = -Sin; 
    rotationMatrix(c2, c2) = Cos; 

    return rotationMatrix; 
} 
+0

좋아 보인다. 질문의 대답과 코드의 가독성에 대해 의견을 말합니까? 당신은 무엇을 위해 갈 것이고, 그 이유는 무엇입니까? –

+0

@Nasser는 나를 위해, 괜찮아 보인다. 피터의 의견을 고려해 보면 코드가 '최대'및 '최소'기능을 필요로하지 않고 (심지어 초판에 쓴 것처럼) 더 간단해진다는 점에 유의하십시오. –

+0

좋은 소리, 고마워! –