diff --git a/src/vector.cpp b/src/vector.cpp
new file mode 100644
--- /dev/null
+++ b/src/vector.cpp
@@ -0,0 +1,341 @@
+/*
+ *
+ * This file is part of the Virtual Leaf.
+ *
+ * The Virtual Leaf 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.
+ *
+ * The Virtual Leaf 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