Vectors and matrices in D

Artyom Shalkhakov artyom.shalkhakov at gmail.com
Mon Mar 12 20:54:38 PDT 2007


Hello!

First of all, thanks to WB for this awesome language! :)

I've got a couple of silly newbie questions.
I started implementing a little raytracer in D (raytracing is addictive, yeah ;)), and faced problems with vector/matrix math :(

struct Vec3 {
    float opIndex( int index ) {
        assert( index >= 0 && index < 3 );
        return ( &x )[index];
    }

    void opIndexAssign( float f, int index ) {
        assert( index >= 0 && index < 3 );
        ( &x )[index] = f;
    }

    Vec3 opAddAssign( inout Vec3 v ) {
        x += v.x;
        y += v.y;
        z += v.z;

        return *this;
    }
/*
    // on C++
    Vec3 &operator+=( const Vec3 &v ) {
        x += v.x;
        y += v.y;
        z += v.z;

        return *this;
    }
*/

    float x, y, z;
}

struct Mat3 {
    // I think that copying is costly here..
    Vec3 opIndex( int index ) {
        return rows[index];
    }
/*
    // this is how it looked like on C++
    Vec3 &operator[]( const int index ) {
        assert( index >= 0 && index < 3 );
        return rows[index];
    }
    const Vec3 &operator( const int index ) {
        assert( index >= 0 && index < 3 );
        return rows[index];
    }
*/

    void opIndexAssign( Vec3 v, int index ) {
        rows[index] = v;
    }

    private Vec3 rows[3];
}

unittest {
    Mat3   m;

    m[0][0] = 1.0f;
    assert( m[0][0] == 1.0f );
    // The above assertion fails all the time.
    // I think that DMD interprets m[0][0] as m.opIndex( 0 ).opIndexAssign( 0 ),
    // so it ends up operating on copy of row.
    // Any suggestions?
}

I tried other representations for vectors and matrices, but faced another problem:
what happens when a static array is passed to function?

For example:
alias float[3]  Vec3;

float dot( Vec3 v1, Vec3 v2 ) {
    return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2];
}

If I get it correctly, the code above is identical to:

float dot( size_t length1, float *v1, size_t length2, float *v1 ) {
    return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2];
}

Lengths of two arrays will never ever change, therefore two parameters are redundant. This is an overhead I'm trying to avoid. Can anyone tell me should I really care?

Thanks in advance!


More information about the Digitalmars-d-learn mailing list