vectormath库和矩阵运算

时间:2015-12-03 06:14:58

标签: c linear-algebra matrix-multiplication vectormath

我发现这个copy on github要链接到,但我使用从sourceforge下载的那个。

我对他们设计矩阵运算方式的问题对我来说似乎很奇怪。

例如,如果我创建一个4×4矩阵并设置它的比例。然后我想使用vectormath矩阵库旋转前一个矩阵似乎将矩阵重置回一个单位矩阵,然后应用旋转,这对于为什么会发生这种情况没有任何意义。

看看这个函数进行旋转

static inline void vmathM4MakeRotationY( VmathMatrix4 *result, float radians )
{
    float s, c;
    s = sinf( radians );
    c = cosf( radians );
    vmathV4MakeFromElems( &result->col0, c, 0.0f, -s, 0.0f );
    vmathV4MakeYAxis( &result->col1 );
    vmathV4MakeFromElems( &result->col2, s, 0.0f, c, 0.0f );
    vmathV4MakeWAxis( &result->col3 );
}

这个库是否期望你保持多个矩阵使用一个来应用旋转然后相乘?

修改

这是我用来旋转矩阵的一些先前的矩阵数学代码,它看起来像这样。

mat4_s mat4_rotateX(mat4_s* out, float angle, mat4_s* inMat)
{
    float s = sinf(angle),
            c = cosf(angle),
            a10 = inMat->m[4],
            a11 = inMat->m[5],
            a12 = inMat->m[6],
            a13 = inMat->m[7],
            a20 = inMat->m[8],
            a21 = inMat->m[9],
            a22 = inMat->m[10],
            a23 = inMat->m[11];

    if (!out->m) {
        for(size_t i = 0; i < 16; i++)
        {
            out->m[i] = inMat->m[i];
        }
    } else if (inMat->m != out->m) { // If the source and destination differ, copy the unchanged rows
        out->m[0] = inMat->m[0];
        out->m[1] = inMat->m[1];
        out->m[2] = inMat->m[2];
        out->m[3] = inMat->m[3];

        out->m[12] = inMat->m[12];
        out->m[13] = inMat->m[13];
        out->m[14] = inMat->m[14];
        out->m[15] = inMat->m[15];
    }


    out->m[4] = a10 * c + a20 * s;
    out->m[5] = a11 * c + a21 * s;
    out->m[6] = a12 * c + a22 * s;
    out->m[7] = a13 * c + a23 * s;

    out->m[8] = a10 * -s + a20 * c;
    out->m[9] = a11 * -s + a21 * c;
    out->m[10] = a12 * -s + a22 * c;
    out->m[11] = a13 * -s + a23 * c;
    return *out;
}

这是我必须采取的过程,以使vectormath做同样的事情。

mat4* mat4_rotate_y(mat4* out, const float angle){
    mat4 m;
    mat4_identity_v(&m);
    vmathM4MakeRotationY(m, angle);
    mat4_multi(out, out, m);
    return out;
}

乘法代码是相当标准的,但vmathM4MakeRotationY看起来像这样:

static inline void vmathM4MakeRotationZ( VmathMatrix4 *result, float radians )
{
    float s, c;
    s = sinf( radians );
    c = cosf( radians );
    vmathV4MakeFromElems( &result->col0, c, s, 0.0f, 0.0f );
    vmathV4MakeFromElems( &result->col1, -s, c, 0.0f, 0.0f );
    vmathV4MakeZAxis( &result->col2 );
    vmathV4MakeWAxis( &result->col3 );
}

为了完整性,vmathV4Make_Axis看起来像这样:

static inline void vmathV4MakeZAxis(VmathVector4 *result) {
    vmathV4MakeFromElems(result, 0.0f, 0.0f, 1.0f, 0.0f);
}

vmathV4MakeFromElms看起来像这样:

static inline void vmathV4MakeFromElems(VmathVector4 *result, float _x,
                                        float _y, float _z, float _w) {
    result->x = _x;
    result->y = _y;
    result->z = _z;
    result->w = _w;
}

1 个答案:

答案 0 :(得分:1)

此函数似乎执行“将矩阵初始化为旋转变换”而不是您期望的“将旋转变换添加到当前变换”。

如您所说,您可以通过将旋转存储在单独的临时矩阵中然后乘以:

来解决
VmathMatrix4 temp;
vmathM4MakeRotationY(&temp, 1.23);
vmathM4Mul(&mytransform, &mytransform, &temp);

这几乎是假设的vmathM4ApplyRotationY()必须要做的事情。