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

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.

主站蜘蛛池模板: 诸城市| 南和县| 蓬莱市| 法库县| 轮台县| 深圳市| 鲜城| 平度市| 达州市| 教育| 教育| 大同县| 于都县| 林州市| 临洮县| 湘西| 贺兰县| 西丰县| 濮阳市| 安徽省| 阳朔县| 巫溪县| 高陵县| 泸定县| 老河口市| 浠水县| 车险| 吉林市| 大同市| 贡觉县| 威远县| 永顺县| 浦江县| 嵊州市| 宽城| 嘉鱼县| 天祝| 贵定县| 肥乡县| 涪陵区| 崇明县|