官术网_书友最值得收藏!

Creating rotations from one vector to another

Any two-unit vectors can represent points on a sphere. The shortest arc between these points lies on a plane that contains both points and the center of the sphere. This plane

is perpendicular to the axis of rotation between those two vectors.

To find the axis of rotation, normalize the input vectors. Find the cross product of the input vectors. This is the axis of rotation. Find the angle between the input vectors. From Chapter 2, Implementing Vectors, the formula for the angle between two vectors is . Since both input vectors are normalized, this simplifies to , which means that the cosine of θ is the dot product of the input vectors:

You will recall from Chapter 2, Implementing Vectors, that the dot product has a relationship to the cosine of the angle between two vectors, and that the cross product has a relationship to the sine of the angle between two vectors. When creating quaternions, the dot and cross product have the following properties:

The cross product can be expanded into x, y, and z components and the previous equation starts to look like the code for creating a quaternion from an angle and an axis of rotation. Finding the angle between the two vectors would be expensive, but the half-angle can be counted without knowing what the angle is.

To find the half-angle, find the halfway vector between the v1 and v2 input vectors. Construct a quaternion using v1 and this halfway vector. This will create a quaternion that results in the desired rotation.

There is one edge case—what happens when v1 and v2 are parallel? Or if v1== -v2 ? The cross product that's used to find the axis of rotation would yield a 0 vector. If this edge case happens, find the most perpendicular vector between the two vectors to create a pure quaternion.

Perform the following steps to implement the fromTo function:

  1. Begin to implement the fromTo function in quat.cpp and add the function declaration to quat.h. Start by normalizing the from and to vectors, making sure they are not the same vector:

    quat fromTo(const vec3& from, const vec3& to) {

       vec3 f = normalized(from);

       vec3 t = normalized(to);

       if (f == t) {

          return quat();

       }

  2. Next, check whether the two vectors are opposites of each other. If they are, the most orthogonal axis of the from vector can be used to create a pure quaternion:

       else if (f == t * -1.0f) {

          vec3 ortho = vec3(1, 0, 0);

          if (fabsf(f.y) <fabsf(f.x)) {

             ortho = vec3(0, 1, 0);

          }

          if (fabsf(f.z)<fabs(f.y) && fabs(f.z)<fabsf(f.x)){

             ortho = vec3(0, 0, 1);

          }

          vec3 axis = normalized(cross(f, ortho));

          return quat(axis.x, axis.y, axis.z, 0);

       }

  3. Finally, create a half vector between the from and to vectors. Use the cross product of the half vector and the starting vector to calculate the axis of rotation and the dot product of the two to find the angle of rotation:

       vec3 half = normalized(f + t);

       vec3 axis = cross(f, half);

       return quat(axis.x, axis.y, axis.z, dot(f, half));

    }

The fromTo function is one of the most intuitive ways of creating a quaternion. Next, you're going to learn how to retrieve the angle and the axis that define a quaternion.

主站蜘蛛池模板: 长丰县| 临颍县| 都兰县| 青冈县| 辛集市| 阿合奇县| 石屏县| 安顺市| 聂拉木县| 自贡市| 萍乡市| 托里县| 德兴市| 阿拉善盟| 喜德县| 永嘉县| 临泉县| 合江县| 日土县| 铜鼓县| 井研县| 苗栗市| 莱州市| 曲靖市| 平泉县| 全南县| 随州市| 仁寿县| 玛沁县| 高尔夫| 平和县| 恭城| 绍兴县| 扬州市| 洞头县| 辽源市| 扎赉特旗| 慈溪市| 云和县| 海城市| 迁安市|