3

I am trying to rotate a group of vectors I sampled to the normal of a triangle

If this was correct, the randomly sampled hemisphere would line up with the triangle.

Currently I generate it on the Z-axis and am attempting to rotate all the samples to the normal of the triangle.

but it seems to be "just off"

enter image description here

glm::quat getQuat(glm::vec3 v1, glm::vec3 v2)
{

    glm::quat myQuat;
    float dot = glm::dot(v1, v2);
    if (dot != 1)
    {
        glm::vec3 aa = glm::normalize(glm::cross(v1, v2));
        float w = sqrt(glm::length(v1)*glm::length(v1) * glm::length(v2)*glm::length(v2)) + dot;
        myQuat.x = aa.x;
        myQuat.y = aa.y;
        myQuat.z = aa.z;
        myQuat.w = w;
    }
    return myQuat;
}

Which I pulled from the bottom of this page : http://lolengine.net/blog/2013/09/18/beautiful-maths-quaternion-from-vectors

Then I :

glm::vec3 zaxis = glm::normalize( glm::vec3(0, 0, 1) );  // hardcoded but test orginal axis
glm::vec3 n1 = glm::normalize( glm::cross((p2 - p1), (p3 - p1)) ); //normal
glm::quat myQuat = glm::normalize(getQuat(zaxis, n1));

glm::mat4 rotmat = glm::toMat4(myQuat); //make a rotation matrix
glm::vec4 n3 = rotmat * glm::vec4(n2,1); // current vector I am trying to rotate
Noah Witherspoon
  • 57,021
  • 16
  • 130
  • 131
Joe
  • 81
  • 1
  • 7

1 Answers1

10

Construct 4x4 transform matrix instead of Quaternions.

img

  1. Do not forget that OpenGL has column wise matrix

    so for double m[16];
    is X axis vector in m[ 0],m[ 1],m[ 2]
    is Y axis vector in m[ 4],m[ 5],m[ 6]
    is Z axis vector in m[ 8],m[ 9],m[10]
    and position is in m[12],m[13],m[14]

    The LCS mean local coordinate system (your triangle or object or whatever)
    and GCS mean global coordinate system (world or whatever).

    All the X,Y,Z vectors should be normalized to unit vectors otherwise scaling will occur.

  2. construction

    1. set Z-axis vector to your triangle normal
    2. set position (LCS origin) to mid point of your triangle (or average point form its vertexes)
    3. now you just need X and Y axises which is easy

      let X = any triangle vertex - triangle midpoint
      or X = substraction of any 2 vertexes of triangle

      The only condition that must be met for X is that it must lie on triangle plane.
      Now let Y = X x Z the cross product will create vector perpendicular to X and Z (which also lies in triangle plane).

    4. now put all this inside matrix and load it to OpenGL as ModelView matrix or what ever.

Spektre
  • 49,595
  • 11
  • 110
  • 380
  • Would this be susceptible to gimbal lock ever? – Joe Aug 09 '14 at 17:53
  • @Joe have no clue what gimbal lock means (dictionary of mine knows only gimbal head) but if you want to align/lock your points to the triangle (not just its plane) then put the origin (x0,y0,z0) and one axis to the same way (respect to triangle) in each frame or iteration or what ever. so if origin is the avg vertex of triangle (mid point `(P0+P1+P2)/3`) and X (or Y) axis points to the same triangle vertex for example `(P0-((P0+P1+P2)/3))` then what ever triangle position/orientation your hemisphere will align to it always the same way (even if triangle change shape) – Spektre Aug 10 '14 at 07:56
  • Gimbal lock is the loss of a degree of freedom as part of a series of rotations (i.e. `next_transform = rotate_func(current_transform)`). What you're trying to do here isn't really rotation in the sense of quantities varying over time; it just generates a new transform every frame based on the input. – Justin Apr 21 '15 at 12:36
  • @Joe no "gimbal lock" is just Euler angles and quaternions related one of many quirks they have. transform matrices have no rotation restrictions nor singularities. – Spektre Apr 22 '20 at 06:47