3D vector, 4D homogenous vector or both?

262e3cd9c428c4fa981b049a04d4a113
0
Mihulik 101 Jan 03, 2010 at 09:22

Hi,
when you implement your vector math library do you use ordinary 3D vector or 4D homogenous vector? Or both?
I mean in general case.

If I had 3D vector I’d supply w-coordinate when I need it.

However, if I had 4D vector, how would I compute vector operations (dot product, cross product and so on)? Like 3D and keep w on some value (1 or 0?)?
Or compute in 4D? But in this case, can I make cross product in 4D?

Or do you make both classes? In this case, API would be messy(somewhere 3D vector, somewhere 4D vector,…), wouldn’t it?

I hope that I’ve explained my question in understandable way:-)

Thank you for any advise!

8 Replies

Please log in or register to post a reply.

6aa952514ff4e5439df1e9e6d337b864
0
roel 101 Jan 03, 2010 at 13:33

I hope I understood your question correctly. Most of the time you’ll only need 3d vectors, as most of the time you know it’s type: a point (w=1) or normal (w=0). Only in special parts of your code you might require 4d vectors, but rarely. Most of the time it is a waste of space to store w and most of the time it is a waste of time to matrix multiply with w if it is 1 or 0. At least that is my experience, I’m a humble hobby-coder :)

99f6aeec9715bb034bba93ba2a7eb360
0
Nick 102 Jan 03, 2010 at 15:41

There’s generally no need to waste your time creating a “vector math library”. Most projects use vector math in only a few distinct places, in well-defined ways. So often you’ll even be able to just use a plain array of floats, instead of intricate classes. That approach also makes it easier to debug things. I once had the ‘pleasure’ of working with a powerful templatize library which ended up costing me more time figuring out why some results were not as expected, than it saved me time coding.

KISS

262e3cd9c428c4fa981b049a04d4a113
0
Mihulik 101 Jan 03, 2010 at 15:51

roel: You understood me well:-) It’s what I thought.
Nick: You’re absolute right. I don’t want to develop big “vector math library”.
I just want to have some wrapper class(es) which encapsulates me common vector operations (dot product, cross product and so on). No huge template inheritance positive monster;-)

340bf64ac6abda6e40f7e860279823cb
0
_oisyn 101 Jan 03, 2010 at 21:42

@Nick

That approach also makes it easier to debug things.

Why? Why would a float[3] be easier to debug than a struct Vector3 { float x, y, z; }? And coding-wise is a float[3] a lot more inconvenient than a struct (you can’t return them from functions for example)

I once had the ‘pleasure’ of working with a powerful templatize library which ended up costing me more time figuring out why some results were not as expected, than it saved me time coding.

Yes I think those are awful too, but that doesn’t mean you shouldn’t use a vector math library in general.

A8433b04cb41dd57113740b779f61acb
0
Reedbeta 167 Jan 03, 2010 at 23:05

@Nick

Most projects use vector math in only a few distinct places, in well-defined ways.

:) I don’t know what kinds of projects you’ve been working on, but in my experience game projects use vector math all over the place, for all sorts of purposes. Do you really want to have to write three addition statements (or even a function call that wraps them) every time you need to add a couple vectors? I’d never code any serious 3D project without a solid vector-matrix math library with overloaded operators.

You don’t have to choose between using float[3] and using some crazy templatized thing…there is a middle ground. ;)

262e3cd9c428c4fa981b049a04d4a113
0
Mihulik 101 Jan 05, 2010 at 18:56

Thank you all for your replies.

I implemented three separate classes for 2D/3D/4D vector today and …surprise…my hands didn’t start to crying when I had finished writing sources:-)

I’m sorry for wasting forum space:-)

99f6aeec9715bb034bba93ba2a7eb360
0
Nick 102 Jan 06, 2010 at 10:35

@.oisyn

Why? Why would a float[3] be easier to debug than a struct Vector3 { float x, y, z; }?

I wasn’t suggesting to only use float[3]. I was merely saying that in a lot of cases you can use simple constructs, which also facilitates debugging.@Reedbeta

You don’t have to choose between using float[3] and using some crazy templatized thing…there is a middle ground.

Sure. But there’s no need to waste time pondering whether to use 3D or 4D vectors, or both, either. Just implement what you need as you go. Especially when you’re still struggling with questions like this it’s easy to lose the bigger picture. So my advice would be to keep things as simple as possible. That really doesn’t mean operator overloading and things like that should be avoided at all cost. But don’t bloat your code with things you’re not sure will be needed.

Anyway, practically, I’d suggest to start out with a 4D vector struct. It can represent 3D vectors and points and can be transformed using 4x4 matrices to perform translations and projections.@Mihulik

However, if I had 4D vector, how would I compute vector operations (dot product, cross product and so on)?

You can have a dot3 and dot4 function for 3D and 4D dot products respectively. For the cross product you can simply ignore w and assume it to be 0. It makes no sense to compute the cross product of points anyway. You might be tempted to enforce this by using different classes for vectors and points, but seriously, if you’re attempting to take the cross product of two points you have bigger issues than type safety. In other situations, points can actually be displacement vectors, so you can save explicit conversion.

For things like addition, simply add each component invididually (which makes sense for vector-vector, point-vector, but not point-point). Don’t worry about performance. If it really matters (near the end of the project), you can still write specialized routines for that, possibly even using assembly.

340bf64ac6abda6e40f7e860279823cb
0
_oisyn 101 Jan 06, 2010 at 14:08

@Nick

I wasn’t suggesting to only use float[3]. I was merely saying that in a lot of cases you can use simple constructs, which also facilitates debugging.

You were more or less implying that using a vector library does NOT facilitate debugging, and that you therefore should use simple constructs. The struct I defined could very well be part of a vector library.

Btw, while a distinction between vectors and points is essentially correct, it isn’t very convenient from a usability standpoint 9 out of 10 times. I would therefore indeed suggest to use a single construct, and have different functions when you actually need the distinction (such as when transforming using a matrix)