Vectors and matrices in D

Bill Baxter dnewsgroup at billbaxter.com
Tue Mar 13 09:00:31 PDT 2007


Artyom Shalkhakov wrote:
> 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!

Some general suggestions:
* Search the NG archives for "raytracer".  There was a thread about a 
simple raytracer implementation in C++ and D and its performance in the 
two.  There was code for a working raytracer that might be useful for 
you as an example, but also in the thread numerous performance issues 
were discussed, like for instance the cost passing Vec3 type structs 
around by value.

* Look at helix for one way to implement vector/matrix classes. 
http://www.dsource.org/projects/helix

--bb


More information about the Digitalmars-d-learn mailing list