Designing the Vector3D class
I don't know which is the best practice, when we want to create a new vector 3D class, I mean which of these two examples is the best way?
class Vec3D
{
private:
float m_fX;
float m_fY;
float m_fZ;
...
};
or
class Vec3D
{
private:
float m_vVec[3];
...
};
With the first aproach we have separate variables, we cannot be contiguous in memory, so the caches can fail, but accessing those variables is one instruction.
In the second aproach we have a vector of 3 contiguous floats in memory, the caches are fine here, but each access will make an additional amount of variable offset. Booty thinks this vectorial approach might better match optimizations like SSE2 / 3 or something.
Which aproach is better, I'm lost, I need advice :)
Thank you for your time:)
LLORENS
source to share
The second will make matrix operations much easier.
Before writing your own vector and matrix classes, you can review the code for something like openscengraph
source to share
Assuming you will be doing heavy computation with your vectors, I would suggest making your members public (or just using a struct instead of a class). You should skip the overhead of getters and just access the elements of the vector directly.
In terms of syntax, the first form is more readable. If you ever need access to members as an array of three values, you might also consider using a union, which gives you access to both individual members and the array.
source to share
I am against the introduction of my own 3D class.
While such a class seems simple enough, it takes incredible work to create an efficient, reliable, reliable, and accurate class of this kind.
There is nothing worse than spending many hours looking for a weird error, only to end up finding that it is caused by a numerical instability in your vector class, generating the wrong answer for a specific input. Trust me, I was there!
There are many libraries available, reviewed and verified by thousands of users, so you can use them with confidence.
A library that I've used successfully for many years is Andrew Willmotts' simple vector library. http://www.cs.cmu.edu/~ajw/doc/svl.html
SVL is simple and straightforward. However, it does have a very outdated API and the problem for me is that this is another third party library that needs to be connected and downloaded by my clients.
So, lately I've been using boost :: uBLAS and in particular a fixed size vector wrapper based on the one described here: http://www.crystalclearsoftware.com/cgi-bin/boost_wiki/wiki.pl?Effective_UBLAS
The acceleration library is, as always, intimidating when you first approach it. However, it is superbly efficient and perfect, actively maintained and shipped for "free" when boost is added in your program anyway.
source to share
From a performance standpoint, the compiler should be able to produce equally efficient code for both. However, there are pros and cons for both.
The first is by far the more readable. However, the second one allows you to grab the variable by index. So if you need to do something like adding all two vectors, this code will be simpler:
for(int i = 0; i < 3; ++i) {
vVec[i] += o.vVec[i];
}
against.
m_fX += o.m_fX; m_fY += o.m_fY; m_fZ += o.m_fZ;
So, I would say no matter what you find more convenient and readable based on what you are trying to achieve.
source to share
I would definitely go for the second approach. In many places in your code, this will allow you to have an elegant loop instead of long repetition. Consider this:
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
VecMult.m_vVec[i] += Vec1.m_vVec[i] * Vec2.m_vVec[j];
}
Compared to this:
VecMult.m_fX = Vec1.m_fX * Vec2.m_fX + Vec1.m_fX * Vec2.m_fY + Vec1.m_fX * Vec2.m_fZ;
VecMult.m_fY = Vec2.m_fX * Vec2.m_fX + Vec2.m_fX * Vec2.m_fY + Vec2.m_fX * Vec2.m_fZ;
VecMult.m_fZ = Vec3.m_fX * Vec2.m_fX + Vec3.m_fX * Vec2.m_fY + Vec3.m_fX * Vec2.m_fZ;
source to share
Both have pros and cons. We usually v1.X * v2.Y
read further v1[0] * v2[1]
. But there are algorithms that index the vector, and write in the second v1[a] * v2[b]
. In this case, the first solution will cause ugly blocks if
or switch
. I'm not a C ++ programmer, but maybe you could get the most out of two using macros or whatever C ++ supports (a union
, as others suggested, seems like a good candidate). In C #, I would create something like the following using properties.
public class Vector
{
private readonly Single[] components = new Single[3];
public Single X
{
get { return components[0]; }
set { this.components[0] = value; }
}
public Single Y { ... }
public Single Z { ... }
}
Finally, I believe that performance will not be an issue as indexing can be handled by CPU address computation units.
source to share