Jump to content


- - - - -

3D vector, 4D homogenous vector or both?


8 replies to this topic

#1 Mihulik

    New Member

  • Members
  • PipPip
  • 13 posts

Posted 03 January 2010 - 09:22 AM

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!

#2 roel

    Senior Member

  • Members
  • PipPipPipPip
  • 698 posts

Posted 03 January 2010 - 01:33 PM

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 :)

#3 Nick

    Senior Member

  • Members
  • PipPipPipPip
  • 1227 posts
  • LocationOttawa, Ontario, Canada

Posted 03 January 2010 - 03:41 PM

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

#4 Mihulik

    New Member

  • Members
  • PipPip
  • 13 posts

Posted 03 January 2010 - 03:51 PM

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;-)

#5 .oisyn

    DevMaster Staff

  • Moderators
  • 1842 posts

Posted 03 January 2010 - 09:42 PM

Nick said:

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)

Quote

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.
C++ addict
-
Currently working on: the 3D engine for Tomb Raider.

#6 Reedbeta

    DevMaster Staff

  • Administrators
  • 5344 posts
  • LocationSanta Clara, CA

Posted 03 January 2010 - 11:05 PM

Nick said:

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. ;)
reedbeta.com - developer blog, OpenGL demos, and other projects

#7 Mihulik

    New Member

  • Members
  • PipPip
  • 13 posts

Posted 05 January 2010 - 06:56 PM

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:-)

#8 Nick

    Senior Member

  • Members
  • PipPipPipPip
  • 1227 posts
  • LocationOttawa, Ontario, Canada

Posted 06 January 2010 - 10:35 AM

.oisyn said:

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 said:

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 said:

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.

#9 .oisyn

    DevMaster Staff

  • Moderators
  • 1842 posts

Posted 06 January 2010 - 02:08 PM

Nick said:

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)
C++ addict
-
Currently working on: the 3D engine for Tomb Raider.





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users