/*
*
* This file is part of the Virtual Leaf.
*
* VirtualLeaf is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* VirtualLeaf 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with the Virtual Leaf. If not, see .
*
* Copyright 2010 Roeland Merks.
*
*/
#include
#include
#include
#include
#include
//#include
#include
#include "sqr.h"
#include "pi.h"
#include "vector.h"
#include "tiny.h"
static const std::string _module_id("$Id$");
void Vector::operator=(const Vector &source) {
// assignment
// don't assign to self
if (this==&source) return;
x=source.x;
y=source.y;
z=source.z;
}
ostream &Vector::print(ostream &os) const {
os << "(" << x << ", " << y << ", " << z << ")";
return os;
}
ostream &operator<<(ostream &os, const Vector &v) {
v.print(os);
return os;
}
Vector Vector::operator+(const Vector &v) const {
Vector result;
result.x=x+v.x;
result.y=y+v.y;
result.z=z+v.z;
return result;
}
Vector& Vector::operator-=(const Vector &v) {
x-=v.x;
y-=v.y;
z-=v.z;
return *this;
}
Vector Vector::operator/(const double divisor) const {
Vector result;
result.x=x/divisor;
result.y=y/divisor;
result.z=z/divisor;
return result;
}
Vector Vector::operator*(const double multiplier) const {
Vector result;
result.x=x*multiplier;
result.y=y*multiplier;
result.z=z*multiplier;
return result;
}
Vector operator*(const double multiplier, const Vector &v) {
Vector result;
result.x=v.x*multiplier;
result.y=v.y*multiplier;
result.z=v.z*multiplier;
return result;
}
Vector &Vector::operator/=(const double divisor) {
x/=divisor;
y/=divisor;
z/=divisor;
return *this;
}
Vector &Vector::operator*=(const double multiplier) {
x*=multiplier;
y*=multiplier;
z*=multiplier;
return *this;
}
Vector Vector::operator*(const Vector &v) const {
// cross product ("uitproduct")
Vector result;
result.x=y*v.z-z*v.y;
result.y=z*v.x-x*v.z;
result.z=x*v.y-y*v.x;
return result;
}
double InnerProduct(const Vector &v1, const Vector &v2) {
// Inner product ("inproduct")
double result;
result=v1.x*v2.x+v1.y*v2.y+v1.z*v2.z;
return result;
}
double Vector::Angle(const Vector &v) const {
// angle between this vector and another vector
// angle is within range of [0,pi] radians
// angle is arccosine of the inner product over the product of the norms of the vectors
double cos_angle=InnerProduct(*this,v)/(Norm()*v.Norm());
// check for computational inaccuracies
if (cos_angle<=-1)
return Pi;
if (cos_angle>=1)
return 0.;
double angle=acos(cos_angle);
return angle;
}
double Vector::SignedAngle(const Vector &v) const {
// angle between this vector and another vector
// angle is within range of [-pi,pi] radians
// angle is arccosine of the inner product over the product of the norms of the vectors
double cos_angle=InnerProduct(*this,v)/(Norm()*v.Norm());
// check for computational inaccuracies
if (cos_angle<=-1)
return Pi;
if (cos_angle>=1)
return 0.;
double angle=acos(cos_angle);
double sign = (InnerProduct ( Perp2D(), v ) )>0.?1.:-1.;
return angle * sign;
}
bool Vector::operator==(const Vector &v) const {
// "sloppy equal"
if ((fabs(x-v.x)0.) { // if the norm is 0, don't normalise
// (otherwise division by zero occurs)
(*this)/=norm;
}
}
Vector Vector::Normalised(void) const {
double norm;
norm=Norm(); // Absolute value;
if (norm>0.) { // if the norm is 0, don't normalise
// (otherwise division by zero occurs)
return (*this)/norm;
} else {
return *this;
}
}
bool Vector::SameDirP(const Vector &v) {
// return true if the two (parallel) vectors point in the same direction
// if (x*v.x>=0 && y*v.y>=0 && z*v.z>=0)
double angle=Angle(v);
if (angle<(Pi/2))
return true;
else
return false;
}
double Vector::Max(void) {
// Find maximum value of vector
double max;
max=x > y ? x : y;
max=max > z ? max : z;
return max;
}
double Vector::Min(void) {
// Find minimum value of vector
double min;
min=x < y ? x : y;
min=min < z ? min : z;
return min;
}
// test
#ifdef TEST
void main() {
Vector v(1.,2.,3.);
Vector d;
d=5*v;
// cerr << d << "\n";
d=v*5;
// cerr << d << "\n";
d=v/5;
// cerr << d << "\n";
// cerr << d.Norm() << "\n";
d.Normalise();
// cerr << d << " " << d.Norm() << "\n";
}
#endif
/* finis */