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

Transforming vectors and points

Transforming points and vectors is done in the same way as multiplying matrices. In fact, the vector being transformed can be thought of as a matrix with 4 columns and 1 row. This means transforming vectors is a matter of multiplying a 4 x 4 and a 4 x 1 matrix together.

When a matrix transforms a vector, it affects both the orientation and scale of the vector. When a matrix transforms a point, it just translates the point in space. So, what's the difference between vectors and points? The w component of a vector is 0 and the W component of a point is 1. The following steps will guide you through implementing matrix-vector multiplication:

  1. To make the matrix-vector multiplication a little easier to read, you will need to once again create a macro. This macro will take the row of a matrix and perform a dot product of that row against the provided column vector. Implement the M4VD macro in mat4.cpp:

    #define M4V4D(mRow, x, y, z, w) \

        x * m.v[0 * 4 + mRow] + \

        y * m.v[1 * 4 + mRow] + \

        z * m.v[2 * 4 + mRow] + \

        w * m.v[3 * 4 + mRow]

  2. With the M4V4D macro in place, implement the matrix-vector multiplication function in mat4.cpp. Don't forget to add the function definition to mat4.h:

    vec4 operator*(const mat4& m, const vec4& v) {

        return vec4(

            M4V4D(0, v.x, v.y, v.z, v.w),

            M4V4D(1, v.x, v.y, v.z, v.w),

            M4V4D(2, v.x, v.y, v.z, v.w),

            M4V4D(3, v.x, v.y, v.z, v.w)

        );

    }

  3. Most of the data in this book will be stored as three-component vectors, not four. There is no need to create a new four-component vector every time one needs to be transformed by a matrix; instead, you will create a specialized function for just this occasion.
  4. Define a new function in mat4.cpp: transformVector. Don't forget to add the function declaration to mat4.h. This function will take vec3 and transform it using the provided matrix, assuming the vector represents the direction and magnitude:

    vec3 transformVector(const mat4& m, const vec3& v) {

        return vec3(

            M4V4D(0, v.x, v.y, v.z, 0.0f),

            M4V4D(1, v.x, v.y, v.z, 0.0f),

            M4V4D(2, v.x, v.y, v.z, 0.0f)

        );

    }

  5. Next, define the transformPoint function in mat4.cpp. It should multiply the vector and the matrix, assuming that the W component of the vector is 1:

    vec3 transformPoint(const mat4& m, const vec3& v) {

        return vec3(

            M4V4D(0, v.x, v.y, v.z, 1.0f),

            M4V4D(1, v.x, v.y, v.z, 1.0f),

            M4V4D(2, v.x, v.y, v.z, 1.0f)

        );

    }

  6. Define an overload for transformPoint that takes an additional W component. The W component is a reference—it is a read-write. After the function is executed, the w component holds the value for W, if the input vector had been vec4:

    vec3 transformPoint(const mat4& m, const vec3& v, float& w) {

        float _w = w;

        w = M4V4D(3, v.x, v.y, v.z, _w);

        return vec3(

            M4V4D(0, v.x, v.y, v.z, _w),

            M4V4D(1, v.x, v.y, v.z, _w),

            M4V4D(2, v.x, v.y, v.z, _w)

        );

    }

Throughout the rest of this book, most data is stored in vec3 structures. This means transformVector and transformPoint will be used, rather than the overloaded multiplication operator. This should help reduce ambiguity as to what the data being transformed is. Next, you will learn how to invert a matrix.

主站蜘蛛池模板: 麻江县| 平谷区| 都昌县| 日喀则市| 盐池县| 红河县| 广汉市| 建湖县| 禄劝| 札达县| 千阳县| 周口市| 禹州市| 清丰县| 庄浪县| 修文县| 呼和浩特市| 顺昌县| 呼图壁县| 安陆市| 高州市| 容城县| 临清市| 呈贡县| 和平县| 晋宁县| 延川县| 无极县| 南安市| 柳州市| 东乡族自治县| 呼伦贝尔市| 剑川县| 府谷县| 广南县| 天峨县| 沙洋县| 诸暨市| 木兰县| 平罗县| 灵石县|