You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

206 lines
5.7 KiB

#ifndef Magnum_Math_Vector_h
#define Magnum_Math_Vector_h
/*
15 years ago
Copyright © 2010, 2011, 2012 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::Math::Vector
*/
#include <cstring>
#include <cmath>
#include "Utility/Debug.h"
#include "TypeTraits.h"
namespace Magnum { namespace Math {
15 years ago
/** @brief %Vector */
template<class T, size_t size> class Vector {
public:
15 years ago
typedef T Type; /**< @brief Vector data type */
const static size_t Size = size; /**< @brief Vector size */
/** @brief Angle between vectors */
inline static T angle(const Vector<T, size>& a, const Vector<T, size>& b) {
return acos((a*b)/(a.length()*b.length()));
}
/** @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) {
if(&other != this) 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 {
for(size_t pos = 0; pos != size; ++pos)
if(!TypeTraits<T>::equals(at(pos), other.at(pos))) return false;
return true;
}
/** @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(0);
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 Negative vector */
Vector<T, size> operator-() const {
Vector<T, size> out;
for(size_t i = 0; i != size; ++i)
out.set(i, -at(i));
return out;
}
/** @brief Vector length */
inline T length() const {
return sqrt(operator*(*this));
}
/** @brief Normalized vector (of length 1) */
inline Vector<T, size> normalized() const {
return *this/length();
}
/** @brief Product of values in the vector */
T product() const {
T out = 1;
for(size_t i = 0; i != size; ++i)
out *= at(i);
return out;
}
private:
T _data[size];
};
#ifndef DOXYGEN_GENERATING_OUTPUT
template<class T, size_t size> Corrade::Utility::Debug operator<<(Corrade::Utility::Debug debug, const Magnum::Math::Vector<T, size>& value) {
debug << "Vector(";
debug.setFlag(Corrade::Utility::Debug::SpaceAfterEachValue, false);
for(size_t i = 0; i != size; ++i) {
if(i != 0) debug << ", ";
debug << value.at(i);
}
debug << ')';
debug.setFlag(Corrade::Utility::Debug::SpaceAfterEachValue, true);
return debug;
}
#endif
}}
#endif