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

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.

主站蜘蛛池模板: 手游| 张家川| 成安县| 东方市| 巢湖市| 陆良县| 怀仁县| 渭源县| 崇仁县| 水富县| 榆树市| 江北区| 皋兰县| 土默特左旗| 墨脱县| 时尚| 察雅县| 龙游县| 凭祥市| 玉屏| 汶川县| 闸北区| 乡城县| 邢台县| 八宿县| 蓬溪县| 雅江县| 塔城市| 莒南县| 海阳市| 吉水县| 襄汾县| 正定县| 泰安市| 山东| 雷波县| 本溪市| 沙湾县| 平远县| 崇文区| 罗源县|