www.digitalmars.com         C & C++   DMDScript  

D - Vector math

reply billy_zelsnack <billy_zelsnack_member pathlink.com> writes:
What is considered the best way to layout and manipulate vectors?

(I prefer manipulating with functions rather than operator overloads)

The first thing I tried was using a static array, but the compiler won't let me
return a static array from a function..

float[3] add(float[3] vA,float[3] vB) //nope, can't do this

I then tried using a struct like I do in c++.

struct float3
{
float[3] _value;

float opIndex(int i)
{
return _value[i];
}

int opIndex(int i,float value)
{
_value[i]=value;
return i;
}
}

float3 add(float3 vA,float3 vB) //-- yes, this works

The problem is it is really convienient to have a constructor in there and the
compiler doesn't like me doing that. A constructor lets you do cool stuff like..

float3 value=add(float3(0,0,0),float3(1,1,1));

Instead of..

float3 posA;
posA.set(0,0,0);
float3 posB;
posB.set(1,1,1);
float3 value=add(posA,posB);

Is there a way to make a constructor work with a struct? I guess I could use a
helper function like..

float3 float3_make(float x,float y,float z) //but it is not as nice

Also. Are structs always passed by value to functions? In c++ my vector add
function would look something like this..

float3 add(const float3& vA,const float3& vB)
{
return float3(vA[0]+vB[0],vA[1]+vB[1],vA[2]+vB[2]);
}

or even worse..

float3 localToWorld(const float16& mA,const float3& vA);

Is there a way to tell the compiler to pass something by reference, but not
allow modification of the variable?
Apr 14 2004
next sibling parent reply Ben Hinkle <bhinkle4 juno.com> writes:
On Wed, 14 Apr 2004 07:31:37 +0000 (UTC), billy_zelsnack
<billy_zelsnack_member pathlink.com> wrote:

What is considered the best way to layout and manipulate vectors?

(I prefer manipulating with functions rather than operator overloads)

The first thing I tried was using a static array, but the compiler won't let me
return a static array from a function..

float[3] add(float[3] vA,float[3] vB) //nope, can't do this

I then tried using a struct like I do in c++.

struct float3
{
float[3] _value;

float opIndex(int i)
{
return _value[i];
}

int opIndex(int i,float value)
{
_value[i]=value;
return i;
}
}

float3 add(float3 vA,float3 vB) //-- yes, this works

The problem is it is really convienient to have a constructor in there and the
compiler doesn't like me doing that. A constructor lets you do cool stuff like..

float3 value=add(float3(0,0,0),float3(1,1,1));

Instead of..

float3 posA;
posA.set(0,0,0);
float3 posB;
posB.set(1,1,1);
float3 value=add(posA,posB);

Is there a way to make a constructor work with a struct? 
I can't remember who first discovered it but a static opCall works: static float3 opCall(float x, float y, float z) { float3 v; v.set(x,y,z); return v; }
 I guess I could use a helper function like..

float3 float3_make(float x,float y,float z) //but it is not as nice

Also. Are structs always passed by value to functions? In c++ my vector add
function would look something like this..

float3 add(const float3& vA,const float3& vB)
{
return float3(vA[0]+vB[0],vA[1]+vB[1],vA[2]+vB[2]);
}

or even worse..

float3 localToWorld(const float16& mA,const float3& vA);

Is there a way to tell the compiler to pass something by reference, but not
allow modification of the variable?
nope. 'inout' or 'out' will pass by reference but 'const' is reserved for compile-time constants.
Apr 14 2004
parent reply billy_zelsnack <billy_zelsnack_member pathlink.com> writes:
In article <e8tp70d62quvt8c4132o0ilcade5hbjo7q 4ax.com>, Ben Hinkle says...
On Wed, 14 Apr 2004 07:31:37 +0000 (UTC), billy_zelsnack
<billy_zelsnack_member pathlink.com> wrote:

What is considered the best way to layout and manipulate vectors?

(I prefer manipulating with functions rather than operator overloads)

The first thing I tried was using a static array, but the compiler won't let me
return a static array from a function..

float[3] add(float[3] vA,float[3] vB) //nope, can't do this

I then tried using a struct like I do in c++.

struct float3
{
float[3] _value;

float opIndex(int i)
{
return _value[i];
}

int opIndex(int i,float value)
{
_value[i]=value;
return i;
}
}

float3 add(float3 vA,float3 vB) //-- yes, this works

The problem is it is really convienient to have a constructor in there and the
compiler doesn't like me doing that. A constructor lets you do cool stuff like..

float3 value=add(float3(0,0,0),float3(1,1,1));

Instead of..

float3 posA;
posA.set(0,0,0);
float3 posB;
posB.set(1,1,1);
float3 value=add(posA,posB);

Is there a way to make a constructor work with a struct? 
I can't remember who first discovered it but a static opCall works: static float3 opCall(float x, float y, float z) { float3 v; v.set(x,y,z); return v; }
 I guess I could use a helper function like..

float3 float3_make(float x,float y,float z) //but it is not as nice

Also. Are structs always passed by value to functions? In c++ my vector add
function would look something like this..

float3 add(const float3& vA,const float3& vB)
{
return float3(vA[0]+vB[0],vA[1]+vB[1],vA[2]+vB[2]);
}

or even worse..

float3 localToWorld(const float16& mA,const float3& vA);

Is there a way to tell the compiler to pass something by reference, but not
allow modification of the variable?
nope. 'inout' or 'out' will pass by reference but 'const' is reserved for compile-time constants.
Apr 14 2004
parent reply billy_zelsnack <billy_zelsnack_member pathlink.com> writes:
In article <c5j16t$t97$1 digitaldaemon.com>, billy_zelsnack says...
In article <e8tp70d62quvt8c4132o0ilcade5hbjo7q 4ax.com>, Ben Hinkle says...
On Wed, 14 Apr 2004 07:31:37 +0000 (UTC), billy_zelsnack
<billy_zelsnack_member pathlink.com> wrote:

What is considered the best way to layout and manipulate vectors?

(I prefer manipulating with functions rather than operator overloads)

The first thing I tried was using a static array, but the compiler won't let me
return a static array from a function..

float[3] add(float[3] vA,float[3] vB) //nope, can't do this

I then tried using a struct like I do in c++.

struct float3
{
float[3] _value;

float opIndex(int i)
{
return _value[i];
}

int opIndex(int i,float value)
{
_value[i]=value;
return i;
}
}

float3 add(float3 vA,float3 vB) //-- yes, this works

The problem is it is really convienient to have a constructor in there and the
compiler doesn't like me doing that. A constructor lets you do cool stuff like..

float3 value=add(float3(0,0,0),float3(1,1,1));

Instead of..

float3 posA;
posA.set(0,0,0);
float3 posB;
posB.set(1,1,1);
float3 value=add(posA,posB);

Is there a way to make a constructor work with a struct? 
I can't remember who first discovered it but a static opCall works: static float3 opCall(float x, float y, float z) { float3 v; v.set(x,y,z); return v; }
 I guess I could use a helper function like..

float3 float3_make(float x,float y,float z) //but it is not as nice

Also. Are structs always passed by value to functions? In c++ my vector add
function would look something like this..

float3 add(const float3& vA,const float3& vB)
{
return float3(vA[0]+vB[0],vA[1]+vB[1],vA[2]+vB[2]);
}

or even worse..

float3 localToWorld(const float16& mA,const float3& vA);

Is there a way to tell the compiler to pass something by reference, but not
allow modification of the variable?
nope. 'inout' or 'out' will pass by reference but 'const' is reserved for compile-time constants.
Apr 14 2004
parent billy_zelsnack <billy_zelsnack_member pathlink.com> writes:
What the hell. Where did my post go? Ahh. Let's quickly try again.

I tried timing a couple of variants.

//-- 0.675178 seconds
float3 add0(inout float3 vA,inout float3 vB)
{
return float3(vA[0]+vB[0],vA[1]+vB[1],vA[2]+vB[2]);
}

//-- 0.813258 seconds
float3 add1(inout float3 vA,inout float3 vB)
{
float [] arA=vA.array;
float [] arB=vB.array;
return float3(arA[0]+arB[0],arA[1]+arB[1],arA[2]+arB[2]);
}

//-- 0.413748 seconds
float3 add2(float[] vA,float[] vB)
{
return float3(vA[0]+vB[0],vA[1]+vB[1],vA[2]+vB[2]);
}

//-- 0.363559 seconds
float3 add3(float* vA,float* vB)
{
return float3(vA[0]+vB[0],vA[1]+vB[1],vA[2]+vB[2]);
}

//-- 0.233136 seconds
void add4(float[3] vA,float[3] vB,float[3] result)
{
result[0]=vA[0]+vB[0];
result[1]=vA[1]+vB[1];
result[2]=vA[2]+vB[2];
}

//-- 0.193447 seconds
void opAddAssign(float[3] vA)
{
_value[0]+=vA[0];
_value[1]+=vA[1];
_value[2]+=vA[2];
}

//-- 0.191404 seconds (c++)
inline float3 add(const float3& vA,const float3& vB)
{
return float3(vA[0]+vB[0],vA[1]+vB[1],vA[2]+vB[2]);
}

The whole benchmark is at:
http://rafb.net/paste/results/Ulj93024.html

I am going to get more familiar with the language and benchmark again later.
Speedy vector math is important to my current project as big chunk of it is a
realtime physics simulator ( www.shapemaniac.com/bziotd.php ). I guess I could
do some parts in C, but I would rather not.
Apr 15 2004
prev sibling next sibling parent Alix Pexton <Alix thedjournal.com> writes:
billy_zelsnack wrote:

8<-- snip -->8

Is there a way to tell the compiler to pass something by reference, but not
allow modification of the variable?



  
You could try using DBC, adding a 'in' block to your function that creates a copy of the argument you want to preserve, and an 'out' block that throws an assert if the value has changed. Some thing like this untested example... void someFunc(inout int noChange) in{ int checkNoChange = noChange; } out{ assert(checkNoChange == noChange); } body{ ... } Of course the asserts will be stripped from a release build, but by then the code should have been tested, and you should know that it works as desired... Alix... -- Alix Pexton Webmaster - http://www.theDjournal.com Alix theDjournal.com
Apr 14 2004
prev sibling parent John Reimer <jjreimer telus.net> writes:
billy_zelsnack wrote:
 What is considered the best way to layout and manipulate vectors?
 
 (I prefer manipulating with functions rather than operator overloads)
 
<snip> Dig has some nifty vector types (vec2,vec3,vec4). You might like to look at what it does even though it does implement operator overloads. Most recent version (unDig): http://badmama.com.au/~anderson/JA's_D_Page.html Have a peek in .\dig\net\BurtonRadons\dig\common\math.d Later, John
Apr 14 2004