#ifndef _VECTOR3_H #define _VECTOR3_H #include #include template class Vector3 { T _x, _y, _z; public: Vector3() : _x{}, _y{}, _z{} {} Vector3( T x_, T y_, T z_ ) : _x{x_}, _y{y_}, _z{z_} {} inline T x() const { return _x; } inline T y() const { return _y; } inline T z() const { return _z; } T norm() const; T normsq() const; friend std::istream& operator>>( std::istream &is, Vector3 &vec ) { is >> vec._x >> vec._y >> vec._z; return is; } }; template inline T Vector3::normsq() const { return _x * _x + _y * _y + _z * _z; } template inline T Vector3::norm() const { return sqrt( normsq() ); } template<> inline float Vector3::norm() const { return sqrtf( normsq() ); } template inline const Vector3 operator+( const Vector3 &a, const Vector3 &b ) { return Vector3{ a.x() + b.x(), a.y() + b.y(), a.z() + b.z() }; } template inline const Vector3 operator-( const Vector3 &a, const Vector3 &b ) { return Vector3{ a.x() - b.x(), a.y() - b.y(), a.z() - b.z() }; } // Vector * scalar template inline const Vector3 operator*( const Vector3 &a, T b ) { return Vector3{ a.x() * b, a.y() * b, a.z() * b }; } // scalar * Vector template inline const Vector3 operator*( T a, const Vector3 &b ) { return Vector3{ a * b.x(), a * b.y(), a * b.z() }; } // Vector / scalar template inline const Vector3 operator/( const Vector3 &a, T b ) { return Vector3{ a.x() / b, a.y() / b, a.z() / b }; } // Other useful math template inline T dot( const Vector3 &a, const Vector3 &b ) { return a.x() * b.x() + a.y() * b.y() + a.z() * b.z(); } template inline Vector3 cross( const Vector3 &a, const Vector3 &b ) { return Vector3{ a.y() * b.z() - a.z() * b.y(), a.z() * b.x() - a.x() * b.z(), a.x() * b.y() - a.y() * b.x() }; } template inline T cube( T x ) { return x * x * x; } template std::ostream& operator<<( std::ostream &os, const Vector3 &vec ) { os << vec.x() << " " << vec.y() << " " << vec.z(); return os; } typedef Vector3 Vector3f; typedef Vector3 Vector3d; typedef Vector3 Vector3i; #endif // _VECTOR3_H