www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Points and Vectors in 3D

reply Caligo <iteronvexor gmail.com> writes:
Given everything that D offers, what would be the best way to implement a
Point and a Vector type?  The same (x, y, z) can be used to represent
vectors, but a point represents a position, whereas a vector represents a
direction.  So, would you define two different structs for each? or define
and implement an interface?  a fixed array or POD members?
Mar 12 2011
parent reply Simon <s.d.hammett gmail.com> writes:
On 12/03/2011 20:51, Caligo wrote:
 Given everything that D offers, what would be the best way to implement
 a Point and a Vector type?  The same (x, y, z) can be used to represent
 vectors, but a point represents a position, whereas a vector represents
 a direction.  So, would you define two different structs for each? or
 define and implement an interface?  a fixed array or POD members?
I've done lots of 3d over the years and used quite a lot of different libraries and I've come to prefer code that makes a distinction between points and vectors. Makes code easier to read and more type safe, though it's a bit more inconvenient when you need to mix things up. I use: struct pt { float[3] _vals; } struct vec { float[3] _vals; } Using the float[3] allows you to use vector ops: pt p0; vec v; p0._vals[] += v._vals[]; You don't want an interface; you don't get anything more value type than points & vectors. In a modern 3d models you could be dealing with a 1/2 million vertices. -- My enormous talent is exceeded only by my outrageous laziness. http://www.ssTk.co.uk
Mar 12 2011
parent reply Bekenn <leaveme alone.com> writes:
On 3/12/2011 2:20 PM, Simon wrote:
 I've done lots of 3d over the years and used quite a lot of different
 libraries and I've come to prefer code that makes a distinction between
 points and vectors.
Agreed. This has some nice benefits with operator overloading, as well: vec v = ...; pt p = ...; auto p2 = p + v; // p2 is pt auto p3 = p + p2; // error auto v2 = v + v; // v2 is vec ...and with properties: p.x = 5; // p is pt, sets p._vals[0] v.dx = 3; // v is vec, sets v._vals[0]
Mar 12 2011
parent reply Spacen Jasset <spacenjasset yahoo.co.uk> writes:
On 13/03/2011 00:06, Bekenn wrote:
 On 3/12/2011 2:20 PM, Simon wrote:
 I've done lots of 3d over the years and used quite a lot of different
 libraries and I've come to prefer code that makes a distinction between
 points and vectors.
Agreed. This has some nice benefits with operator overloading, as well: vec v = ...; pt p = ...; auto p2 = p + v; // p2 is pt auto p3 = p + p2; // error auto v2 = v + v; // v2 is vec ...and with properties: p.x = 5; // p is pt, sets p._vals[0] v.dx = 3; // v is vec, sets v._vals[0]
Would you then go on to define things like a cross product as an operator overload?
Mar 13 2011
parent reply "Simen kjaeraas" <simen.kjaras gmail.com> writes:
Spacen Jasset <spacenjasset yahoo.co.uk> wrote:

 On 13/03/2011 00:06, Bekenn wrote:
 On 3/12/2011 2:20 PM, Simon wrote:
 I've done lots of 3d over the years and used quite a lot of differen=
t
 libraries and I've come to prefer code that makes a distinction betw=
een
 points and vectors.
Agreed. This has some nice benefits with operator overloading, as wel=
l:
 vec v =3D ...;
 pt p =3D ...;
 auto p2 =3D p + v; // p2 is pt
 auto p3 =3D p + p2; // error
 auto v2 =3D v + v; // v2 is vec

 ...and with properties:

 p.x =3D 5; // p is pt, sets p._vals[0]
 v.dx =3D 3; // v is vec, sets v._vals[0]
Would you then go on to define things like a cross product as an =
 operator overload?
Can't see a fitting operator in D. Multiplication (*) is ambiguous at be= st and no other operator seems fitting. I'd like to have more of unicode's mathematical operators and symbols[1]= as operators in D, but currently that's beyond the horizon. Use cases: Vector a, b; auto angle =3D a =E2=88=A0 b; assert( a =3D=3D (b =E2=88=93 .1) ); assert( ( a =E2=88=9F b ) =3D=3D ( angle =3D=3D degrees( 90 ) ) ); assert( a =E2=88=A5 b ); auto v =3D a =E2=8B=85 b; Set c =3D =E2=88=85, d =3D =E2=88=85; auto union =3D c =E2=88=AA d; auto intersection =3D c =E2=88=A9 d; assert( "foo" =E2=88=88 c ); assert( "foo" =E2=88=89 d ); assert( d =E2=88=8C "foo" ); assert( c =E2=88=8B "foo" ); assert( d =E2=8A=82 c ); assert( d =E2=8A=85 c ); assert( =E2=88=8F[1,2,3] =3D=3D =E2=88=91[1,2,3] ); Of course, this requires a method for typing these symbols, something which TeX has already solved for us. [1]: = http://en.wikipedia.org/wiki/Mathematical_operators_and_symbols_in_Unico= de -- = Simen
Mar 13 2011
next sibling parent reply Simon <s.d.hammett gmail.com> writes:
On 13/03/2011 14:11, Simen kjaeraas wrote:
 Spacen Jasset <spacenjasset yahoo.co.uk> wrote:

 On 13/03/2011 00:06, Bekenn wrote:
 On 3/12/2011 2:20 PM, Simon wrote:
 I've done lots of 3d over the years and used quite a lot of different
 libraries and I've come to prefer code that makes a distinction between
 points and vectors.
Agreed. This has some nice benefits with operator overloading, as well: vec v = ...; pt p = ...; auto p2 = p + v; // p2 is pt auto p3 = p + p2; // error auto v2 = v + v; // v2 is vec ...and with properties: p.x = 5; // p is pt, sets p._vals[0] v.dx = 3; // v is vec, sets v._vals[0]
Would you then go on to define things like a cross product as an operator overload?
Can't see a fitting operator in D. Multiplication (*) is ambiguous at best and no other operator seems fitting.
Convention is to use ^ as cross product and * as dot product. -- My enormous talent is exceeded only by my outrageous laziness. http://www.ssTk.co.uk
Mar 13 2011
parent reply "Simen kjaeraas" <simen.kjaras gmail.com> writes:
On Sun, 13 Mar 2011 15:43:09 +0100, Simon <s.d.hammett gmail.com> wrote:

 On 13/03/2011 14:11, Simen kjaeraas wrote:
 Spacen Jasset <spacenjasset yahoo.co.uk> wrote:

 On 13/03/2011 00:06, Bekenn wrote:
 On 3/12/2011 2:20 PM, Simon wrote:
 I've done lots of 3d over the years and used quite a lot of different
 libraries and I've come to prefer code that makes a distinction  
 between
 points and vectors.
Agreed. This has some nice benefits with operator overloading, as well: vec v = ...; pt p = ...; auto p2 = p + v; // p2 is pt auto p3 = p + p2; // error auto v2 = v + v; // v2 is vec ...and with properties: p.x = 5; // p is pt, sets p._vals[0] v.dx = 3; // v is vec, sets v._vals[0]
Would you then go on to define things like a cross product as an operator overload?
Can't see a fitting operator in D. Multiplication (*) is ambiguous at best and no other operator seems fitting.
Convention is to use ^ as cross product and * as dot product.
Really? I've never heard of it. Rather, everyone I've talked to about it has said exactly what I did. -- Simen
Mar 13 2011
parent Simon <s.d.hammett gmail.com> writes:
On 13/03/2011 15:29, Simen kjaeraas wrote:
 On Sun, 13 Mar 2011 15:43:09 +0100, Simon <s.d.hammett gmail.com> wrote:
 Convention is to use ^ as cross product and * as dot product.
Really? I've never heard of it. Rather, everyone I've talked to about it has said exactly what I did.
Openscenegraph uses those conventions and I've seen it used elsewhere as well. Not sure where they originated though. Seeing as dot & cross product are very common, having them as operators is really handy. -- My enormous talent is exceeded only by my outrageous laziness. http://www.ssTk.co.uk
Mar 13 2011
prev sibling parent Caligo <iteronvexor gmail.com> writes:
On Sun, Mar 13, 2011 at 9:11 AM, Simen kjaeraas <simen.kjaras gmail.com>wrote:

 Spacen Jasset <spacenjasset yahoo.co.uk> wrote:

 Can't see a fitting operator in D. Multiplication (*) is ambiguous at best
 and no other operator seems fitting.
I agree. It's just better do define 'dot' and 'cross'. That's how it's done in Eigen and it works great.
Mar 13 2011