/***************************************************************************
* Copyright (C) 2005 by Raphael Langerhorst *
* raphael-langerhorst@gmx.at *
* *
* Permission is hereby granted, free of charge, to any person obtaining *
* a copy of this software and associated documentation files (the *
* "Software"), to deal in the Software without restriction, including *
* without limitation the rights to use, copy, modify, merge, publish, *
* distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to *
* the following conditions: *
* *
* The above copyright notice and this permission notice shall be *
* included in all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, *
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR *
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, *
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR *
* OTHER DEALINGS IN THE SOFTWARE. *
***************************************************************************/
#include "GVector3.h"
#include <qstring.h>
namespace GCS
{
GVector3::GVector3() :
x(0),
y(0),
z(0)
{
}
GVector3::GVector3(const double d) :
x(d),
y(d),
z(d)
{
}
GVector3::GVector3(const double x, const double y, const double z) :
x(x),
y(y),
z(z)
{
}
GVector3::GVector3(const double* component) :
x(component[0]),
y(component[1]),
z(component[2])
{
}
GVector3::GVector3(const GVector3& original) :
x(original.x),
y(original.y),
z(original.z)
{
}
double GVector3::length() const
{
return std::sqrt(x*x + y*y + z*z);
}
double GVector3::lengthsq() const
{
return x*x + y*y + z*z;
}
GVector3& GVector3::reset()
{
x=y=z=0;
return *this;
}
GVector3& GVector3::set(double x, double y, double z)
{
this->x = x;
this->y = y;
this->z = z;
return *this;
}
GVector3& GVector3::set(const GVector3& original)
{
return set(original.x, original.y, original.z);
}
GVector3& GVector3::normalize()
{
double l = length();
x /= l;
y /= l;
z /= l;
return *this;
}
GVector3& GVector3::scaleXYZ(double x, double y, double z)
{
this->x *= x;
this->y *= y;
this->z *= z;
return *this;
}
GVector3& GVector3::scaleXYZ(const GVector3& scale)
{
return scaleXYZ(scale.x,scale.y,scale.z);
}
GVector3& GVector3::add(const GVector3& right)
{
x += right.x;
y += right.y;
z += right.z;
return *this;
}
GVector3& GVector3::sub(const GVector3& right)
{
x -= right.x;
y -= right.y;
z -= right.z;
return *this;
}
GVector3& GVector3::mul(double scalar)
{
x *= scalar;
y *= scalar;
z *= scalar;
return *this;
}
double GVector3::dot(const GVector3& right) const
{
return x*right.x +
y*right.y +
z*right.z;
}
GVector3 GVector3::cross(const GVector3& right) const
{
return GVector3(
y*right.z - z*right.y,
z*right.x - x*right.z,
x*right.y - y*right.x);
}
GVector3& GVector3::operator = (const GVector3& original)
{
return set(original);
}
GVector3 GVector3::operator + (const GVector3& right) const
{
return GVector3(x + right.x,
y + right.y,
z + right.z);
}
GVector3 GVector3::operator - (const GVector3& right) const
{
return GVector3(x - right.x,
y - right.y,
z - right.z);
}
GVector3 GVector3::operator * (double factor) const
{
GVector3 result(*this);
return result.mul(factor);
}
GVector3& GVector3::operator += (const GVector3& right)
{
x += right.x;
y += right.y;
z += right.z;
return *this;
}
GVector3& GVector3::operator -= (const GVector3& right)
{
x -= right.x;
y -= right.y;
z -= right.z;
return *this;
}
bool GVector3::operator == (const GVector3& comp) const
{
double dx,dy,dz;
dx = comp.x - x;
dy = comp.y - y;
dz = comp.z - z;
if (dx<0)
dx = -dx;
if (dy<0)
dy = -dy;
if (dz<0)
dz = -dz;
double tolerance = 0.00001; //IMPORTANT, otherwise you will NEVER get two equal double values
return ( dx < tolerance && dy < tolerance && dz < tolerance );
}
double GVector3::distanceTo(const GVector3& p) const
{
GVector3 temp = p - *this;
return temp.length();
}
double GVector3::angleTo(const GVector3& v) const
{
if (this->length()==0 || v.length() == 0)
return 0;
return std::acos(this->dot(v)/(this->length()*v.length()));
}
GVector3& GVector3::turnAroundAxis(const GVector3& axis, double angle_rad)
{
double x,y,z;
double sin_a = std::sin(angle_rad);
double cos_a = std::cos(angle_rad);
x = ( axis.x * axis.x + cos_a * ( 1- axis.x * axis.x ) ) * this->x
+ ( axis.x * axis.y * ( 1 - cos_a ) - axis.z * sin_a ) * this->y
+ ( axis.x * axis.z * ( 1 - cos_a ) + axis.y * sin_a ) * this->z;
y = ( axis.x * axis.y * ( 1 - cos_a ) + axis.z * sin_a ) * this->x
+ ( axis.y * axis.y + cos_a * ( 1- axis.y * axis.y ) ) * this->y
+ ( axis.y * axis.z * ( 1 - cos_a ) - axis.x * sin_a ) * this->z;
z = ( axis.z * axis.x * ( 1 - cos_a ) - axis.y * sin_a ) * this->x
+ ( axis.y * axis.z * ( 1 - cos_a ) + axis.x * sin_a ) * this->y
+ ( axis.z * axis.z + cos_a * ( 1 - axis.z * axis.z ) ) * this->z;
this->x = x;
this->y = y;
this->z = z;
return *this;
}
GVector3& GVector3::projectTo(const GVector3& v)
{
double v_length = v.length();
if (v_length==0)
return *this;
GVector3 temp = v;
*this = temp.mul( v.dot(*this)/(v_length*v_length) );
return *this;
}
QString GVector3::toString()
{
return QString("%1, %2, %3").arg(QString::number(x),QString::number(y),QString::number(z));
}
}
syntax highlighted by Code2HTML, v. 0.9.1