Thread overview
Points and Vectors in 3D
Mar 12, 2011
Caligo
Mar 12, 2011
Simon
Mar 13, 2011
Bekenn
Mar 13, 2011
Spacen Jasset
Mar 13, 2011
Simen kjaeraas
Mar 13, 2011
Simon
Mar 13, 2011
Simen kjaeraas
Mar 13, 2011
Simon
Mar 13, 2011
Caligo
March 12, 2011
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?


March 12, 2011
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
March 13, 2011
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]
March 13, 2011
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?
March 13, 2011
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.

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 = a ∠ b;
assert( a == (b ∓ .1) );
assert( ( a ∟ b ) == ( angle == degrees( 90 ) ) );
assert( a ∥ b );
auto v = a ⋅ b;


Set c = ∅, d = ∅;

auto union = c ∪ d;
auto intersection = c ∩ d;

assert( "foo" ∈ c );
assert( "foo" ∉ d );
assert( d ∌ "foo" );
assert( c ∋ "foo" );

assert( d ⊂ c );
assert( d ⊅ c );

assert( ∏[1,2,3] == ∑[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_Unicode

-- 
Simen
March 13, 2011
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
March 13, 2011
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
March 13, 2011
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.


March 13, 2011
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