/* ** ClanLib SDK ** Copyright (c) 1997-2005 The ClanLib Team ** ** This software is provided 'as-is', without any express or implied ** warranty. In no event will the authors be held liable for any damages ** arising from the use of this software. ** ** Permission is granted to anyone to use this software for any purpose, ** including commercial applications, and to alter it and redistribute it ** freely, subject to the following restrictions: ** ** 1. The origin of this software must not be misrepresented; you must not ** claim that you wrote the original software. If you use this software ** in a product, an acknowledgment in the product documentation would be ** appreciated but is not required. ** 2. Altered source versions must be plainly marked as such, and must not be ** misrepresented as being the original software. ** 3. This notice may not be removed or altered from any source distribution. ** ** Note: Some of the libraries ClanLib may link to may have additional ** requirements or restrictions. ** ** File Author(s): ** ** Magnus Norddahl ** (if your name is missing here, please add it) */ #include "Core/precomp.h" #include "API/Core/Math/cl_vector.h" #include "API/Core/System/cl_assert.h" #include CL_Vector::CL_Vector(float x, float y, float z, float w) { this->x = x; this->y = y; this->z = z; this->w = w; } CL_Vector::CL_Vector(const CL_Vector &other) { x = other.x; y = other.y; z = other.z; w = other.w; } float CL_Vector::norm() const { #ifdef WIN32 return (float)sqrt(x*x+y*y+z*z); #else return std::sqrt(x*x+y*y+z*z); #endif } void CL_Vector::normalize() { float f = norm(); if (f!=0) { x /= f; y /= f; z /= f; } } float CL_Vector::dot(const CL_Vector& v) const { return x*v.x + y*v.y + z*v.z; } float CL_Vector::angle(const CL_Vector& v) const { #ifdef WIN32 return (float)acos(dot(v)/(norm()*v.norm())); #else return std::acos(dot(v)/(norm()*v.norm())); #endif } CL_Vector CL_Vector::cross(const CL_Vector& v) const { CL_Vector tmp = CL_Vector(y * v.z - z * v.y, z * v.x - x * v.z, x * v.y - y * v.x); return tmp; } // quick hack, same as glRotatef(angle, a); CL_Vector CL_Vector::rotate(float angle, const CL_Vector& a) const { CL_Vector tmp = CL_Vector(); #ifdef WIN32 float s = (float)sin(angle); float c = (float)cos(angle); #else float s = std::sin(angle); float c = std::cos(angle); #endif tmp.x = x*(a.x*a.x*(1-c)+c) + y*(a.x*a.y*(1-c)-a.z*s) + z*(a.x*a.z*(1-c)+a.y*s); tmp.y = x*(a.y*a.x*(1-c)+a.z*s) + y*(a.y*a.y*(1-c)+c) + z*(a.y*a.z*(1-c)-a.x*s); tmp.z = x*(a.x*a.z*(1-c)-a.y*s) + y*(a.y*a.z*(1-c)+a.x*s) + z*(a.z*a.z*(1-c)+c); return tmp; } void CL_Vector::round() { x = int(x+0.5f); y = int(y+0.5f); z = int(z+0.5f); w = int(w+0.5f); } CL_Vector CL_Vector::operator * (float s) const { return CL_Vector(s * x, s * y, s * z, s * w); } CL_Vector operator * (float s, const CL_Vector& v) { return CL_Vector(s * v.x, s * v.y, s * v.z, s * v.w); } void CL_Vector::operator += (const CL_Vector& v) { x += v.x; y += v.y; z += v.z; w += v.z; } void CL_Vector::operator -= (const CL_Vector& v) { x -= v.x; y -= v.y; z -= v.z; w -= v.w; } void CL_Vector::operator *= (float s) { x *= s; y *= s; z *= s; w *= s; } CL_Vector CL_Vector::operator + (const CL_Vector& v) const { return CL_Vector(x + v.x, y + v.y, z + v.z, w + v.w); } CL_Vector CL_Vector::operator - (const CL_Vector& v) const { return CL_Vector(x - v.x, y - v.y, z - v.z, w - v.z); } CL_Vector CL_Vector::operator - () const { return CL_Vector(-x, -y, -z, -w); } CL_Vector& CL_Vector::operator = (const CL_Vector& v) { x = v.x; y = v.y; z = v.z; w = v.w; return *this; } bool CL_Vector::operator == (const CL_Vector& v) const { return ((x == v.x) && (y == v.y) && (z == v.z) && (w == v.w)); } bool CL_Vector::operator != (const CL_Vector& v) const { return !(operator == (v)); } float & CL_Vector::operator [] (int n) { switch (n) { case 0: return x; case 1: return y; case 2: return z; case 3: return w; } cl_assert(false); return x; // dummy } std::ostream& operator << (std::ostream& os, const CL_Vector& v) { os << v.x << " " << v.y << " " << v.z; return os; }