Browse Source

Finally "initializer-list" constructor for Vector.

It's not actually initializer list, because it is only for
variable-length types, which is unusable here. Variadic templates do
better job here.
vectorfields
Vladimír Vondruš 14 years ago
parent
commit
7a03e48df8
  1. 8
      src/Math/Test/MatrixTest.cpp
  2. 58
      src/Math/Test/VectorTest.cpp
  3. 7
      src/Math/Vector.h
  4. 4
      src/Math/Vector2.h
  5. 8
      src/Math/Vector3.h
  6. 8
      src/Math/Vector4.h

8
src/Math/Test/MatrixTest.cpp

@ -60,7 +60,7 @@ void MatrixTest::constructZero() {
void MatrixTest::data() {
Matrix4 m(false);
float vector[] = { 4.0f, 5.0f, 6.0f, 7.0f };
Vector4 vector(4.0f, 5.0f, 6.0f, 7.0f);
m.set(3, vector);
m.set(1, 2, 1.0f);
@ -154,11 +154,7 @@ void MatrixTest::multiplyVector() {
1, 3, -3, -4, -1
};
int vector[] = { 0, 5, 3, 4, 4 };
int expected[] = { -24, -35, -32, -25, 1 };
bool is = (Matrix<int, 5>(matrix)*Vector<int, 5>(vector) == Vector<int, 5>(expected));
bool is = (Matrix<int, 5>(matrix)*Vector<int, 5>(0, 5, 3, 4, 4) == Vector<int, 5>(-24, -35, -32, -25, 1));
QVERIFY(is);
}

58
src/Math/Test/VectorTest.cpp

@ -32,9 +32,10 @@ typedef Vector<float, 4> Vector4;
typedef Vector<float, 3> Vector3;
void VectorTest::construct() {
float zero[] = { 0.0f, 0.0f, 0.0f, 0.0f };
QVERIFY((Vector4() == Vector4(0.0f, 0.0f, 0.0f, 0.0f)));
QVERIFY(Vector4() == Vector4(zero));
float data[] = { 1.0f, 2.0f, 3.0f, 4.0f };
QVERIFY((Vector4(data) == Vector4(1.0f, 2.0f, 3.0f, 4.0f)));
}
void VectorTest::data() {
@ -44,8 +45,7 @@ void VectorTest::data() {
v.set(0, 1.0f);
float data[] = { 1.0f, 0.0f, 1.5f, 0.0f };
QVERIFY(v == Vector4(data));
QVERIFY(v == Vector4(1.0f, 0.0f, 1.5f, 0.0f));
}
void VectorTest::bracketOperator() {
@ -85,67 +85,49 @@ void VectorTest::copy() {
}
void VectorTest::dot() {
float first[] = { 1.0f, 0.5f, 0.75f, 1.5f };
float second[] = { 2.0f, 4.0f, 1.0f, 7.0f };
QVERIFY(Vector4(first)*Vector4(second) == 15.25f);
QVERIFY(Vector4(1.0f, 0.5f, 0.75f, 1.5f)*Vector4(2.0f, 4.0f, 1.0f, 7.0f) == 15.25f);
}
void VectorTest::multiplyDivide() {
float vec[] = { 1.0f, 2.0f, 3.0f, 4.0f };
float multiplied[] = { -1.5f, -3.0f, -4.5f, -6.0f };
Vector4 vec(1.0f, 2.0f, 3.0f, 4.0f);
Vector4 multiplied(-1.5f, -3.0f, -4.5f, -6.0f);
QVERIFY(Vector4(vec)*-1.5f == Vector4(multiplied));
QVERIFY(Vector4(multiplied)/-1.5f == Vector4(vec));
QVERIFY(vec*-1.5f == multiplied);
QVERIFY(multiplied/-1.5f == vec);
}
void VectorTest::addSubstract() {
float a[] = { 0.5f, -7.5f, 9.0f, -11.0f };
float b[] = { -0.5, 1.0f, 0.0f, 7.5f };
float expected[] = { 0.0f, -6.5f, 9.0f, -3.5f };
Vector4 a(0.5f, -7.5f, 9.0f, -11.0f);
Vector4 b(-0.5, 1.0f, 0.0f, 7.5f);
Vector4 expected(0.0f, -6.5f, 9.0f, -3.5f);
QVERIFY(Vector4(a)+Vector4(b) == Vector4(expected));
QVERIFY(Vector4(expected)-Vector4(b) == Vector4(a));
QVERIFY(a + b == expected);
QVERIFY(expected - b == a);
}
void VectorTest::length() {
float vec[] = { 1.0f, 2.0f, 3.0f, 4.0f };
QCOMPARE(Vector4(vec).length(), 5.4772256f);
QCOMPARE(Vector4(1.0f, 2.0f, 3.0f, 4.0f).length(), 5.4772256f);
}
void VectorTest::normalized() {
float vec[] = { 1.0f, 1.0f, 1.0f, 1.0f };
float normalized[] = { 0.5f, 0.5f, 0.5f, 0.5f };
QVERIFY(Vector4(vec).normalized() == Vector4(normalized));
QVERIFY(Vector4(1.0f, 1.0f, 1.0f, 1.0f).normalized() == Vector4(0.5f, 0.5f, 0.5f, 0.5f));
}
void VectorTest::product() {
float vec[] = { 1.0f, 2.0f, 3.0f };
QCOMPARE(Vector3(vec).product(), 6.0f);
QCOMPARE(Vector3(1.0f, 2.0f, 3.0f).product(), 6.0f);
}
void VectorTest::angle() {
float a[] = { 2.0f, 3.0f, 4.0f };
float b[] = { 1.0f, -2.0f, 3.0f };
QCOMPARE(Vector3::angle(a, b), rad(1.16251f));
QCOMPARE(Vector3::angle({2.0f, 3.0f, 4.0f}, {1.0f, -2.0f, 3.0f}), rad(1.16251f));
}
void VectorTest::negative() {
float vec[] = { 1.0f, -3.0f, 5.0f, -10.0f };
float negative[] = { -1.0f, 3.0f, -5.0f, 10.0f };
QVERIFY(-Vector4(vec) == negative);
QVERIFY(-Vector4(1.0f, -3.0f, 5.0f, -10.0f) == Vector4(-1.0f, 3.0f, -5.0f, 10.0f));
}
void VectorTest::debug() {
float vec[] = { 0.5f, 15.0f, 1.0f, 1.0f };
ostringstream o;
Debug(&o) << Vector4(vec);
Debug(&o) << Vector4(0.5f, 15.0f, 1.0f, 1.0f);
QCOMPARE(QString::fromStdString(o.str()), QString("Vector(0.5, 15, 1, 1)\n"));
o.str("");

7
src/Math/Vector.h

@ -43,6 +43,13 @@ template<class T, size_t size> class Vector {
memset(_data, 0, size*sizeof(T));
};
/**
* @brief Initializer-list constructor
* @param first First value
* @param next Next values
*/
template<class ...U> inline Vector(T first, U&&... next): _data{first, std::forward<U>(next)...} {}
/**
* @brief Constructor
* @param data Array of @c size length.

4
src/Math/Vector2.h

@ -40,9 +40,7 @@ template<class T> class Vector2: public Vector<T, 2> {
* @param x X value
* @param y Y value
*/
inline Vector2(T x, T y) {
setX(x); setY(y);
}
inline Vector2(T x, T y): Vector<T, 2>(x, y) {}
inline T x() const { return Vector<T, 2>::at(0); } /**< @brief X component */
inline T y() const { return Vector<T, 2>::at(1); } /**< @brief Y component */

8
src/Math/Vector3.h

@ -57,18 +57,14 @@ template<class T> class Vector3: public Vector<T, 3> {
* @param y Y / G value
* @param z Z / B value
*/
inline Vector3(T x, T y, T z) {
setX(x); setY(y); setZ(z);
}
inline Vector3(T x, T y, T z): Vector<T, 3>(x, y, z) {}
/**
* @brief Constructor
* @param other Two component vector
* @param z Z / B value
*/
inline Vector3(const Vector<T, 2>& other, T z = T(0)) {
setX(other[0]); setY(other[1]); setZ(z);
}
inline Vector3(const Vector<T, 2>& other, T z = T(0)): Vector<T, 3>(other[0], other[1], other[2]) {}
inline T x() const { return Vector<T, 3>::at(0); } /**< @brief X component */
inline T y() const { return Vector<T, 3>::at(1); } /**< @brief Y component */

8
src/Math/Vector4.h

@ -48,18 +48,14 @@ template<class T> class Vector4: public Vector<T, 4> {
* @param z Z / B value
* @param w W / A value
*/
inline Vector4(T x, T y, T z, T w = T(1)) {
setX(x); setY(y); setZ(z); setW(w);
}
inline Vector4(T x, T y, T z, T w = T(1)): Vector<T, 4>(x, y, z, w) {}
/**
* @brief Constructor
* @param other Three component vector
* @param w W / A value
*/
inline Vector4(const Vector<T, 3>& other, T w = T(1)) {
setX(other[0]); setY(other[1]); setZ(other[2]); setW(w);
}
inline Vector4(const Vector<T, 3>& other, T w = T(1)): Vector<T, 4>(other[0], other[1], other[2], w) {}
inline T x() const { return Vector<T, 4>::at(0); } /**< @brief X component */
inline T y() const { return Vector<T, 4>::at(1); } /**< @brief Y component */

Loading…
Cancel
Save