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

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.

主站蜘蛛池模板: 山阴县| 秦安县| 伊通| 二连浩特市| 县级市| 丰宁| 崇信县| 丹棱县| 福安市| 安达市| 靖远县| 福海县| 浪卡子县| 银川市| 钦州市| 武清区| 定安县| 右玉县| 金溪县| 岳池县| 平利县| 新闻| 姜堰市| 萝北县| 揭东县| 玛曲县| 香港 | 汾阳市| 土默特右旗| 定安县| 福泉市| 藁城市| 文水县| 慈溪市| 开原市| 桐乡市| 十堰市| 安丘市| 余姚市| 芷江| 边坝县|