Browse Source

Template vector class.

vectorfields
Vladimír Vondruš 16 years ago
parent
commit
2a2d8c3dd5
  1. 1
      src/Test/CMakeLists.txt
  2. 122
      src/Test/VectorTest.cpp
  3. 39
      src/Test/VectorTest.h
  4. 161
      src/Vector.h
  5. 32
      src/constants.h

1
src/Test/CMakeLists.txt

@ -1 +1,2 @@
magnum_add_test(VectorTest VectorTest.h VectorTest.cpp)
magnum_add_test(MatrixTest MatrixTest.h MatrixTest.cpp)

122
src/Test/VectorTest.cpp

@ -0,0 +1,122 @@
/*
Copyright © 2010 Vladimír Vondruš <mosra@centrum.cz>
This file is part of Magnum.
Magnum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License version 3
only, as published by the Free Software Foundation.
Magnum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License version 3 for more details.
*/
#include "VectorTest.h"
#include <cmath>
#include <QtTest/QTest>
#include "Vector.h"
#include "constants.h"
QTEST_APPLESS_MAIN(Magnum::Test::VectorTest)
using namespace std;
namespace Magnum { namespace Test {
typedef Vector<float, 4> Vector4;
void VectorTest::construct() {
float zero[] = { 0.0f, 0.0f, 0.0f, 0.0f };
QVERIFY(Vector4() == Vector4(zero));
}
void VectorTest::data() {
Vector4 v;
v.set(2, 1.0f);
v.add(2, 0.5f);
v.set(0, 1.0f);
float data[] = { 1.0f, 0.0f, 1.5f, 0.0f };
QVERIFY(v == Vector4(data));
}
void VectorTest::bracketOperator() {
Vector4 v1, v2;
v1.set(0, 1.0f);
v1.set(1, v1.at(0));
v1.set(3, 0.5f);
v1.add(3, 2.5f);
v2[0] = 1.0f;
v2[1] = v2[0];
v2[3] = 0.5f;
v2[3] += 2.5f;
QVERIFY(v1 == v2);
}
void VectorTest::copy() {
Vector4 v1;
v1.set(3, 1.0f);
Vector4 v2(v1);
Vector4 v3;
v3.set(0, 0.0f); /* this line is here so it's not optimized to Vector4 v3(v1) */
v3 = v1;
/* Change original */
v1.set(2, 1.0f);
/* Verify the copy is the same as original original */
Vector4 original;
original.set(3, 1.0f);
QVERIFY(v2 == original);
QVERIFY(v3 == original);
}
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);
}
void VectorTest::multiplyDivide() {
float vec[] = { 1.0f, 2.0f, 3.0f, 4.0f };
float multiplied[] = { -1.5f, -3.0f, -4.5f, -6.0f };
QVERIFY(Vector4(vec)*-1.5f == Vector4(multiplied));
QVERIFY(Vector4(multiplied)/-1.5f == Vector4(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 };
QVERIFY(Vector4(a)+Vector4(b) == Vector4(expected));
QVERIFY(Vector4(expected)-Vector4(b) == Vector4(a));
}
void VectorTest::length() {
float vec[] = { 1.0f, 2.0f, 3.0f, 4.0f };
QVERIFY(abs(Vector4(vec).length() - 5.4772256f) < EPSILON);
}
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));
}
}}

39
src/Test/VectorTest.h

@ -0,0 +1,39 @@
#ifndef Magnum_Test_VectorTest_h
#define Magnum_Test_VectorTest_h
/*
Copyright © 2010 Vladimír Vondruš <mosra@centrum.cz>
This file is part of Magnum.
Magnum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License version 3
only, as published by the Free Software Foundation.
Magnum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License version 3 for more details.
*/
#include <QtCore/QObject>
namespace Magnum { namespace Test {
class VectorTest: public QObject {
Q_OBJECT
private slots:
void construct();
void data();
void bracketOperator();
void copy();
void dot();
void multiplyDivide();
void addSubstract();
void length();
void normalized();
};
}}
#endif

161
src/Vector.h

@ -0,0 +1,161 @@
#ifndef Magnum_Vector_h
#define Magnum_Vector_h
/*
Copyright © 2010 Vladimír Vondruš <mosra@centrum.cz>
This file is part of Magnum.
Magnum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License version 3
only, as published by the Free Software Foundation.
Magnum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License version 3 for more details.
*/
/** @file
* @brief Class Magnum::Vector
*/
#include <cstring>
#include <cmath>
namespace Magnum {
/** @brief Vector */
template<class T, size_t size> class Vector {
public:
/** @brief Default constructor */
inline Vector() {
memset(_data, 0, size*sizeof(T));
};
/**
* @brief Constructor
* @param data Array of @c size length.
*/
inline Vector(const T* data) { setData(data); }
/** @brief Copy constructor */
inline Vector(const Vector<T, size>& other) {
setData(other.data());
}
/** @brief Assignment operator */
inline Vector<T, size>& operator=(const Vector<T, size>& other) {
setData(other.data());
return *this;
}
/**
* @brief Raw data
* @return Array of @c size length.
*/
inline const T* data() const { return _data; }
/**
* @brief Set raw data
* @param data Array of @c size length.
*/
inline void setData(const T* data) {
memcpy(_data, data, size*sizeof(T));
}
/** @brief Value at given position */
inline T at(size_t pos) const { return _data[pos]; }
/** @brief Value at given position */
inline T operator[](size_t pos) const { return _data[pos]; }
/** @brief Reference to value at given position */
inline T& operator[](size_t pos) { return _data[pos]; }
/** @brief Set value at given position */
inline void set(size_t pos, T value) { _data[pos] = value; }
/** @brief Add value to given position */
inline void add(size_t pos, T value) { _data[pos] += value; }
/** @brief Equality operator */
inline bool operator==(const Vector<T, size>& other) const {
return memcmp(_data, other.data(), size*sizeof(T)) == 0;
}
/** @brief Non-equality operator */
inline bool operator!=(const Vector<T, size>& other) const {
return !operator==(other);
}
/** @brief Dot product */
T operator*(const Vector<T, size>& other) const {
T out;
for(size_t i = 0; i != size; ++i)
out += at(i)*other.at(i);
return out;
}
/** @brief Multiply vector */
Vector<T, size> operator*(T number) const {
Vector<T, size> out;
for(size_t i = 0; i != size; ++i)
out.set(i, at(i)*number);
return out;
}
/** @brief Divide vector */
Vector<T, size> operator/(T number) const {
Vector<T, size> out;
for(size_t i = 0; i != size; ++i)
out.set(i, at(i)/number);
return out;
}
/** @brief Add two vectors */
Vector<T, size> operator+(const Vector<T, size>& other) const {
Vector<T, size> out;
for(size_t i = 0; i != size; ++i)
out.set(i, at(i)+other.at(i));
return out;
}
/** @brief Substract two vectors */
Vector<T, size> operator-(const Vector<T, size>& other) const {
Vector<T, size> out;
for(size_t i = 0; i != size; ++i)
out.set(i, at(i)-other.at(i));
return out;
}
/** @brief Vector length */
T length() const {
T out;
for(size_t i = 0; i != size; ++i)
out += pow(at(i), 2);
return sqrt(out);
}
/** @brief Normalized vector (of length 1) */
Vector<T, size> normalized() const {
return *this/length();
}
private:
T _data[size];
};
}
#endif

32
src/constants.h

@ -0,0 +1,32 @@
#ifndef Magnum_constants_h
#define Magnum_constants_h
/*
Copyright © 2010 Vladimír Vondruš <mosra@centrum.cz>
This file is part of Magnum.
Magnum is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License version 3
only, as published by the Free Software Foundation.
Magnum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License version 3 for more details.
*/
/** @file
* @brief Constants
*/
namespace Magnum {
/** @brief Pi */
#define PI 3.1415926535
/** @brief Maximal tolerance when comparing doubles */
#define EPSILON 1.0e-8
}
#endif
Loading…
Cancel
Save