*/
Written some cool source code? Upload it to Programmer's Heaven.
*/

View \Vector3D.cpp

Vector3D-class in C++ v0.1

Submitted By: RuntimeTerror
Rating: star (Rate It)


//////////////////////////////////////////////////////////////////////////////////////
// description: represents a 3-dimensional Vector
//
// author: runtimeTerror ([[Email Removed]] - http://www.kaiundina.de)
// last modified: 2003-07-30 20-30
//

#include "Vector3D.h"
#include <math.h>
#include <iostream.h>



//////////////////////////////////////////////////////////////////////////////////////
// Constructors

// constructs the vector (0.0, 0.0, 0.0)
Vector3D::Vector3D() {
        this->x = this->y = this->z = 0;
}

// constructs the vector (xyz, xyz, xyz)
Vector3D::Vector3D(TYPE xyz) {
        this->x = this->y = this->z = xyz;
}

// constructs the vector (x, y, z)
Vector3D::Vector3D(PARAM_T) {
        this->x = x;
        this->y = y;
        this->z = z;
}

// constructs a copy of the vector &v
Vector3D::Vector3D(PARAM_P) {
        this->x = v->x;
        this->y = v->y;
        this->z = v->z;
}

// constructs a copy of the vector v
Vector3D::Vector3D(PARAM_O) {
        this->x = v.x;
        this->y = v.y;
        this->z = v.z;
}


///////////////////////////////////////////////////
// methods for debugging purposes
///////////////////////////////////////////////////

///////////////////////////////////////////////////
// Dumps the data describing the current instance followed by a '\n'
void Vector3D::dump() {
        cout << "(" << this->x << ", " << this->y << ", " << this->z << ")\n";
}

///////////////////////////////////////////////////
// Dumps the data describing the current instance followed by a '\n'
// the string in indent is printed out before each line
void Vector3D::dump(char* indent) {
        cout << indent;
        this->dump();
}


///////////////////////////////////////////////////
// methods using two vectors
// if the first one is omitted, 'this' is used instead
///////////////////////////////////////////////////

///////////////////////////////////////////////////
// adds two vectors

// returns result in a new instance
Vector3D Vector3D::add        (PARAM_TT) { return Vector3D(x1      + x2,    y1      + y2,    z1      + z2   ); }
Vector3D Vector3D::add        (PARAM_TP) { return Vector3D(x1      + v2->x, y1      + v2->y, z1      + v2->z); }
Vector3D Vector3D::add        (PARAM_TO) { return Vector3D(x1      + v2.x,  y1      + v2.y,  z1      + v2.z ); }
Vector3D Vector3D::add        (PARAM_PT) { return Vector3D(v1->x   + x2,    v1->y   + y2,    v1->z   + z2   ); }
Vector3D Vector3D::add        (PARAM_PP) { return Vector3D(v1->x   + v2->x, v1->y   + v2->y, v1->z   + v2->z); }
Vector3D Vector3D::add        (PARAM_PO) { return Vector3D(v1->x   + v2.x,  v1->y   + v2.y,  v1->z   + v2.z ); }
Vector3D Vector3D::add        (PARAM_OT) { return Vector3D(v1.x    + x2,    v1.y    + y2,    v1.z    + z2   ); }
Vector3D Vector3D::add        (PARAM_OP) { return Vector3D(v1.x    + v2->x, v1.y    + v2->y, v1.z    + v2->z); }
Vector3D Vector3D::add        (PARAM_OO) { return Vector3D(v1.x    + v2.x,  v1.y    + v2.y,  v1.z    + v2.z ); }
Vector3D Vector3D::operator + (PARAM_P)  { return Vector3D(this->x + v->x,  this->y + v->y,  this->z + v->z ); }
Vector3D Vector3D::operator + (PARAM_O)  { return Vector3D(this->x + v.x,   this->y + v.y,   this->z + v.z  ); }

// applied on the current instance
Vector3D* Vector3D::add         (PARAM_T) { this->x += x;    this->y += y;    this->z += z;    return this; }
Vector3D* Vector3D::add         (PARAM_P) { this->x += v->x; this->y += v->y; this->z += v->z; return this; }
Vector3D* Vector3D::add         (PARAM_O) { this->x += v.x;  this->y += v.y;  this->z += v.zreturn this; }
Vector3D* Vector3D::operator += (PARAM_P) { this->x += v->x; this->y += v->y; this->z += v->z; return this; }
Vector3D* Vector3D::operator += (PARAM_O) { this->x += v.x;  this->y += v.y;  this->z += v.zreturn this; }

///////////////////////////////////////////////////
// substracts the second from the first vector

// returns result in a new instance
Vector3D Vector3D::sub        (PARAM_TT) { return Vector3D(x1      - x2,    y1      - y2,    z1      - z2   ); }
Vector3D Vector3D::sub        (PARAM_TP) { return Vector3D(x1      - v2->x, y1      - v2->y, z1      - v2->z); }
Vector3D Vector3D::sub        (PARAM_TO) { return Vector3D(x1      - v2.x,  y1      - v2.y,  z1      - v2.z ); }
Vector3D Vector3D::sub        (PARAM_PT) { return Vector3D(v1->x   - x2,    v1->y   - y2,    v1->z   - z2   ); }
Vector3D Vector3D::sub        (PARAM_PP) { return Vector3D(v1->x   - v2->x, v1->y   - v2->y, v1->z   - v2->z); }
Vector3D Vector3D::sub        (PARAM_PO) { return Vector3D(v1->x   - v2.x,  v1->y   - v2.y,  v1->z   - v2.z ); }
Vector3D Vector3D::sub        (PARAM_OT) { return Vector3D(v1.x    - x2,    v1.y    - y2,    v1.z    - z2   ); }
Vector3D Vector3D::sub        (PARAM_OP) { return Vector3D(v1.x    - v2->x, v1.y    - v2->y, v1.z    - v2->z); }
Vector3D Vector3D::sub        (PARAM_OO) { return Vector3D(v1.x    - v2.x,  v1.y    - v2.y,  v1.z    - v2.z ); }
Vector3D Vector3D::operator - (PARAM_P)  { return Vector3D(this->x - v->x,  this->y - v->y,  this->z - v->z ); }
Vector3D Vector3D::operator - (PARAM_O)  { return Vector3D(this->x - v.x,   this->y - v.y,   this->z - v.z  ); }

// applied on the current instance
Vector3D* Vector3D::sub         (PARAM_T) { this->x -= x;    this->y -= y;    this->z -= z;    return this; }
Vector3D* Vector3D::sub         (PARAM_P) { this->x -= v->x; this->y -= v->y; this->z -= v->z; return this; }
Vector3D* Vector3D::sub         (PARAM_O) { this->x -= v.x;  this->y -= v.y;  this->z -= v.zreturn this; }
Vector3D* Vector3D::operator -= (PARAM_P) { this->x -= v->x; this->y -= v->y; this->z -= v->z; return this; }
Vector3D* Vector3D::operator -= (PARAM_O) { this->x -= v.x;  this->y -= v.y;  this->z -= v.zreturn this; }

///////////////////////////////////////////////////
// substracts the first from the second vector

// applied on the current instance
Vector3D* Vector3D::xsub (PARAM_T) { this->x = x - this->x;    this->y = y    - this->y; this->z = z    - this->z; return this; }
Vector3D* Vector3D::xsub (PARAM_P) { this->x = v->x - this->x; this->y = v->y - this->y; this->z = v->z - this->z; return this; }
Vector3D* Vector3D::xsub (PARAM_O) { this->x = v.x - this->x;  this->y = v.y  - this->y; this->z = v.z  - this->z; return this; }


///////////////////////////////////////////////////
// scalar-multiplication of two vectors

// returns result using two external vectors
TYPE Vector3D::smul       (PARAM_TT) { return x1      * x2    + y1      * y2    + z1      * z2;    }
TYPE Vector3D::smul       (PARAM_TP) { return x1      * v2->x + y1      * v2->y + z1      * v2->z; }
TYPE Vector3D::smul       (PARAM_TO) { return x1      * v2.x  + y1      * v2.y  + z1      * v2.z}
TYPE Vector3D::smul       (PARAM_PT) { return v1->x   * x2    + v1->y   * y2    + v1->z   * z2;    }
TYPE Vector3D::smul       (PARAM_PP) { return v1->x   * v2->x + v1->y   * v2->y + v1->z   * v2->z; }
TYPE Vector3D::smul       (PARAM_PO) { return v1->x   * v2.x  + v1->y   * v2.y  + v1->z   * v2.z}
TYPE Vector3D::smul       (PARAM_OT) { return v1.x    * x2    + v1.y    * y2    + v1.z    * z2;    }
TYPE Vector3D::smul       (PARAM_OP) { return v1.x    * v2->x + v1.y    * v2->y + v1.z    * v2->z; }
TYPE Vector3D::smul       (PARAM_OO) { return v1.x    * v2.x  + v1.y    * v2.y  + v1.z    * v2.z}
TYPE Vector3D::operator * (PARAM_P)  { return this->x * v->x  + this->y * v->y  + this->z * v->z;  }
TYPE Vector3D::operator * (PARAM_O)  { return this->x * v.x   + this->y * v.y   + this->z * v.z;   }

// applied with the current instance (no changes will be made)
TYPE Vector3D::smul (PARAM_T) { return this->x * x    + this->y * y    + this->z * z;    }
TYPE Vector3D::smul (PARAM_P) { return this->x * v->x + this->y * v->y + this->z * v->z; }
TYPE Vector3D::smul (PARAM_O) { return this->x * v.x  + this->y * v.y  + this->z * v.z}


///////////////////////////////////////////////////
// crossmultiplies the first with the second vector to obtain a normal vector to both

// returns result in a new instance
Vector3D Vector3D::xmul       (PARAM_TT) { return Vector3D(y1      * z2    - z1      * y2,    z1      * x2    - x1      * z2,    x1      * y2    - y1      * x2   ); }
Vector3D Vector3D::xmul       (PARAM_TP) { return Vector3D(y1      * v2->z - z1      * v2->y, z1      * v2->x - x1      * v2->z, x1      * v2->y - y1      * v2->x); }
Vector3D Vector3D::xmul       (PARAM_TO) { return Vector3D(y1      * v2.z  - z1      * v2.y,  z1      * v2.x  - x1      * v2.z,  x1      * v2.y  - y1      * v2.x ); }
Vector3D Vector3D::xmul       (PARAM_PT) { return Vector3D(v1->y   * z2    - v1->z   * y2,    v1->z   * x2    - v1->x   * z2,    v1->x   * y2    - v1->y   * x2   ); }
Vector3D Vector3D::xmul       (PARAM_PP) { return Vector3D(v1->y   * v2->z - v1->z   * v2->y, v1->z   * v2->x - v1->x   * v2->z, v1->x   * v2->y - v1->y   * v2->x); }
Vector3D Vector3D::xmul       (PARAM_PO) { return Vector3D(v1->y   * v2.z  - v1->z   * v2.y,  v1->z   * v2.x  - v1->x   * v2.z,  v1->x   * v2.y  - v1->y   * v2.x ); }
Vector3D Vector3D::xmul       (PARAM_OT) { return Vector3D(v1.y    * z2    - v1.z    * y2,    v1.z    * x2    - v1.x    * z2,    v1.x    * y2    - v1.y    * x2   ); }
Vector3D Vector3D::xmul       (PARAM_OP) { return Vector3D(v1.y    * v2->z - v1.z    * v2->y, v1.z    * v2->x - v1.x    * v2->z, v1.x    * v2->y - v1.y    * v2->x); }
Vector3D Vector3D::xmul       (PARAM_OO) { return Vector3D(v1.y    * v2.z  - v1.z    * v2.y,  v1.z    * v2.x  - v1.x    * v2.z,  v1.x    * v2.y  - v1.y    * v2.x ); }
Vector3D Vector3D::operator ^ (PARAM_P)  { return Vector3D(this->y * v->z  - this->z * v->y,  this->z * v->x  - this->x * v->z,  this->x * v->y  - this->y * v->x ); }
Vector3D Vector3D::operator ^ (PARAM_O)  { return Vector3D(this->y * v.z   - this->z * v.y,   this->z * v.x   - this->x * v.z,   this->x * v.y   - this->y * v.x  ); }


// applied on the current instance
Vector3D* Vector3D::xmul        (PARAM_T) { return this->set(this->y * z     - this->z * y,     this->z * x     - this->x * z,     this->x * y     - this->y * x    ); }
Vector3D* Vector3D::xmul        (PARAM_P) { return this->set(this->y * v->z  - this->z * v->y,  this->z * v->x  - this->x * v->z,  this->x * v->y  - this->y * v->x ); }
Vector3D* Vector3D::xmul        (PARAM_O) { return this->set(this->y * v.z   - this->z * v.y,   this->z * v.x   - this->x * v.z,   this->x * v.y   - this->y * v.x  ); }
Vector3D* Vector3D::operator ^= (PARAM_P) { return this->set(this->y * v->z  - this->z * v->y,  this->z * v->x  - this->x * v->z,  this->x * v->y  - this->y * v->x ); }
Vector3D* Vector3D::operator ^= (PARAM_O) { return this->set(this->y * v.z   - this->z * v.y,   this->z * v.x   - this->x * v.z,   this->x * v.y   - this->y * v.x  ); }


///////////////////////////////////////////////////
// crossmultiplies the second with the first vector to obtain a normal vector to both

// applied on the current instance
Vector3D* Vector3D::xxmul (PARAM_T) { return this->set(y    * this->z - z    * this->y, z    * this->x - x    * this->z, x    * this->y - y    * this->x); }
Vector3D* Vector3D::xxmul (PARAM_P) { return this->set(v->y * this->z - v->z * this->y, v->z * this->x - v->x * this->z, v->x * this->y - v->y * this->x); }
Vector3D* Vector3D::xxmul (PARAM_O) { return this->set(v.y  * this->z - v.z  * this->y, v.z  * this->x - v.x  * this->z, v.x  * this->y - v.y  * this->x); }

///////////////////////////////////////////////////
// projects the first onto the second vector
// b mustn't be (0.0, 0.0, 0.0)
// a onto b = (a*b)/(b*b)*b

// returns result in a new instance
Vector3D Vector3D::projectTo (PARAM_TT) { return Vector3D(x2, y2, z2) * ((x1    * x2    + y1    * y2    + z1    * z2   ) / (x2    * x2    + y2    * y2    + z2    * z2   )); }
Vector3D Vector3D::projectTo (PARAM_TP) { return Vector3D(v2        ) * ((x1    * v2->x + y1    * v2->y + z1    * v2->z) / (v2->x * v2->x + v2->y * v2->y + v2->z * v2->z)); }
Vector3D Vector3D::projectTo (PARAM_TO) { return Vector3D(v2        ) * ((x1    * v2.x  + y1    * v2.y  + z1    * v2.z ) / (v2.x  * v2.x  + v2.y  * v2.y  + v2.z  * v2.z )); }
Vector3D Vector3D::projectTo (PARAM_PT) { return Vector3D(x2, y2, z2) * ((v1->x * x2    + v1->y * y2    + v1->z * z2   ) / (x2    * x2    + y2    * y2    + z2    * z2   )); }
Vector3D Vector3D::projectTo (PARAM_PP) { return Vector3D(v2        ) * ((v1->x * v2->x + v1->y * v2->y + v1->z * v2->z) / (v2->x * v2->x + v2->y * v2->y + v2->z * v2->z)); }
Vector3D Vector3D::projectTo (PARAM_PO) { return Vector3D(v2        ) * ((v1->x * v2.x  + v1->y * v2.y  + v1->z * v2.z ) / (v2.x  * v2.x  + v2.y  * v2.y  + v2.z  * v2.z )); }
Vector3D Vector3D::projectTo (PARAM_OT) { return Vector3D(x2, y2, z2) * ((v1.x  * x2    + v1.y  * y2    + v1.z  * z2   ) / (x2    * x2    + y2    * y2    + z2    * z2   )); }
Vector3D Vector3D::projectTo (PARAM_OP) { return Vector3D(v2        ) * ((v1.x  * v2->x + v1.y  * v2->y + v1.z  * v2->z) / (v2->x * v2->x + v2->y * v2->y + v2->z * v2->z)); }
Vector3D Vector3D::projectTo (PARAM_OO) { return Vector3D(v2        ) * ((v1.x  * v2.x  + v1.y  * v2.y  + v1.z  * v2.z ) / (v2.x  * v2.x  + v2.y  * v2.y  + v2.z  * v2.z )); }


// applied on the current instance
Vector3D* Vector3D::projectTo (PARAM_T) { return this->set(Vector3D(x, y, z) * ((this->x * x    + this->y * y    + this->z * z   ) / (x    * x    + y    * y    + z    * z   ))); }
Vector3D* Vector3D::projectTo (PARAM_P) { return this->set(Vector3D(v      ) * ((this->x * v->x + this->y * v->y + this->z * v->z) / (v->x * v->x + v->y * v->y + v->z * v->z))); }
Vector3D* Vector3D::projectTo (PARAM_O) { return this->set(Vector3D(v      ) * ((this->x * v.x  + this->y * v.y  + this->z * v.z ) / (v.x  * v.x  + v.y  * v.y  + v.z  * v.z ))); }


///////////////////////////////////////////////////
// projects the second onto the first vector
// a mustn't be (0.0, 0.0, 0.0)
// b onto a = (b*a)/(a*a)*a

// applied on the current instance
Vector3D* Vector3D::projectFrom (PARAM_T) { return this->scale((this->x * x    + this->y * y    + this->z * z   ) / (this->x * this->x + this->y * this->y + this->z * this->z)); }
Vector3D* Vector3D::projectFrom (PARAM_P) { return this->scale((this->x * v->x + this->y * v->y + this->z * v->z) / (this->x * this->x + this->y * this->y + this->z * this->z)); }
Vector3D* Vector3D::projectFrom (PARAM_O) { return this->scale((this->x * v.x  + this->y * v.y  + this->z * v.z ) / (this->x * this->x + this->y * this->y + this->z * this->z)); }


///////////////////////////////////////////////////
// reflects the vector on the plane having the parameter-vector as normal

// applied on the current instance
Vector3D* Vector3D::reflectTo (PARAM_P) { return this->sub(Vector3D::projectTo(this, v) * 2); }

// factor represents the amount of reflection by the surface:
// 0.0 = full absorbation -> result is parallel to the surface
// 1.0 = no absorbation -> same result as 'reflectTo'
Vector3D* Vector3D::reflectAbsorbedTo (PARAM_P, TYPE factor) { return this->sub(Vector3D::projectTo(this, v) * (factor + 1)); }


///////////////////////////////////////////////////
// determines the sine of the smallest angle between two vectors
// none of the vectors must be (0.0, 0.0, 0.0)

// returns result using two external vectors
TYPE Vector3D::sin (PARAM_TT) { return (TYPE)sqrt(Vector3D(y1    * z2    - z1    * y2,    z1    * x2    - x1    * z2,    x1    * y2    - y1    * x2   ).sqr() / (Vector3D(x1, y1, z1).sqr() * Vector3D(x2, y2, z2).sqr())); }
TYPE Vector3D::sin (PARAM_TP) { return (TYPE)sqrt(Vector3D(y1    * v2->z - z1    * v2->y, z1    * v2->x - x1    * v2->z, x1    * v2->y - y1    * v2->x).sqr() / (Vector3D(x1, y1, z1).sqr() * v2->sqr()                 )); }
TYPE Vector3D::sin (PARAM_TO) { return (TYPE)sqrt(Vector3D(y1    * v2.z  - z1    * v2.y,  z1    * v2.x  - x1    * v2.z,  x1    * v2.y  - y1    * v2.x ).sqr() / (Vector3D(x1, y1, z1).sqr() * v2.sqr()                  )); }
TYPE Vector3D::sin (PARAM_PT) { return (TYPE)sqrt(Vector3D(v1->y * z2    - v1->z * y2,    v1->z * x2    - v1->x * z2,    v1->x * y2    - v1->y * x2   ).sqr() / (v1->sqr()                  * Vector3D(x2, y2, z2).sqr())); }
TYPE Vector3D::sin (PARAM_PP) { return (TYPE)sqrt(Vector3D(v1->y * v2->z - v1->z * v2->y, v1->z * v2->x - v1->x * v2->z, v1->x * v2->y - v1->y * v2->x).sqr() / (v1->sqr()                  * v2->sqr()                 )); }
TYPE Vector3D::sin (PARAM_PO) { return (TYPE)sqrt(Vector3D(v1->y * v2.z  - v1->z * v2.y,  v1->z * v2.x  - v1->x * v2.z,  v1->x * v2.y  - v1->y * v2.x ).sqr() / (v1->sqr()                  * v2.sqr()                  )); }
TYPE Vector3D::sin (PARAM_OT) { return (TYPE)sqrt(Vector3D(v1.y  * z2    - v1.z  * y2,    v1.z  * x2    - v1.x  * z2,    v1.x  * y2    - v1.y  * x2   ).sqr() / (v1.sqr()                   * Vector3D(x2, y2, z2).sqr())); }
TYPE Vector3D::sin (PARAM_OP) { return (TYPE)sqrt(Vector3D(v1.y  * v2->z - v1.z  * v2->y, v1.z  * v2->x - v1.x  * v2->z, v1.x  * v2->y - v1.y  * v2->x).sqr() / (v1.sqr()                   * v2->sqr()                 )); }
TYPE Vector3D::sin (PARAM_OO) { return (TYPE)sqrt(Vector3D(v1.y  * v2.z  - v1.z  * v2.y,  v1.z  * v2.x  - v1.x  * v2.z,  v1.x  * v2.y  - v1.y  * v2.x ).sqr() / (v1.sqr()                   * v2.sqr()                  )); }

// applied with the current instance (no changes will be made)
TYPE Vector3D::sin (PARAM_T) { return (TYPE)sqrt(Vector3D(this->y * z    - this->z * y,    this->z * x    - this->x * z,    this->x * y    - this->y * x   ).sqr() / (this->sqr() * Vector3D(x, y, z).sqr())); }
TYPE Vector3D::sin (PARAM_P) { return (TYPE)sqrt(Vector3D(this->y * v->z - this->z * v->y, this->z * v->x - this->x * v->z, this->x * v->y - this->y * v->x).sqr() / (this->sqr() * v->sqr()               )); }
TYPE Vector3D::sin (PARAM_O) { return (TYPE)sqrt(Vector3D(this->y * v.z  - this->z * v.y,  this->z * v.x  - this->x * v.z,  this->x * v.y  - this->y * v.x ).sqr() / (this->sqr() * v.sqr()                )); }


///////////////////////////////////////////////////
// determines the cosine of the smallest angle between two vectors
// none of the vectors must be (0.0, 0.0, 0.0)

// returns result using two external vectors
TYPE Vector3D::cos (PARAM_TT) { return (x1    * x2    + y1    * y2    + z1    * z2   ) / (TYPE)sqrt(Vector3D(x1, y1, z1).sqr() * Vector3D(x2, y2, z2).sqr()); }
TYPE Vector3D::cos (PARAM_TP) { return (x1    * v2->x + y1    * v2->y + z1    * v2->z) / (TYPE)sqrt(Vector3D(x1, y1, z1).sqr() * v2->sqr()                 ); }
TYPE Vector3D::cos (PARAM_TO) { return (x1    * v2.x  + y1    * v2.y  + z1    * v2.z ) / (TYPE)sqrt(Vector3D(x1, y1, z1).sqr() * v2.sqr()                  ); }
TYPE Vector3D::cos (PARAM_PT) { return (v1->x * x2    + v1->y * y2    + v1->z * z2   ) / (TYPE)sqrt(v1->sqr()                  * Vector3D(x2, y2, z2).sqr()); }
TYPE Vector3D::cos (PARAM_PP) { return (v1->x * v2->x + v1->y * v2->y + v1->z * v2->z) / (TYPE)sqrt(v1->sqr()                  * v2->sqr()                 ); }
TYPE Vector3D::cos (PARAM_PO) { return (v1->x * v2.x  + v1->y * v2.y  + v1->z * v2.z ) / (TYPE)sqrt(v1->sqr()                  * v2.sqr()                  ); }
TYPE Vector3D::cos (PARAM_OT) { return (v1.x  * x2    + v1.y  * y2    + v1.z  * z2   ) / (TYPE)sqrt(v1.sqr()                   * Vector3D(x2, y2, z2).sqr()); }
TYPE Vector3D::cos (PARAM_OP) { return (v1.x  * v2->x + v1.y  * v2->y + v1.z  * v2->z) / (TYPE)sqrt(v1.sqr()                   * v2->sqr()                 ); }
TYPE Vector3D::cos (PARAM_OO) { return (v1.x  * v2.x  + v1.y  * v2.y  + v1.z  * v2.z ) / (TYPE)sqrt(v1.sqr()                   * v2.sqr()                  ); }

// applied with the current instance (no changes will be made)
TYPE Vector3D::cos (PARAM_T) { return (this->x * x    + this->y * y    + this->z * z   ) / (TYPE)sqrt(this->sqr() * Vector3D(x, y, z).sqr()); }
TYPE Vector3D::cos (PARAM_P) { return (this->x * v->x + this->y * v->y + this->z * v->z) / (TYPE)sqrt(this->sqr() * v->sqr()               ); }
TYPE Vector3D::cos (PARAM_O) { return (this->x * v.x  + this->y * v.y  + this->z * v.z ) / (TYPE)sqrt(this->sqr() * v.sqr()                ); }


///////////////////////////////////////////////////
// determines the smallest angle between two vectors
// none of the vectors must be (0.0, 0.0, 0.0)

// returns result using two external vectors
TYPE Vector3D::angle (PARAM_TT) { return (TYPE)acos((x1    * x2    + y1    * y2    + z1    * z2   ) / sqrt(Vector3D(x1, y1, z1).sqr() * Vector3D(x2, y2, z2).sqr())); }
TYPE Vector3D::angle (PARAM_TP) { return (TYPE)acos((x1    * v2->x + y1    * v2->y + z1    * v2->z) / sqrt(Vector3D(x1, y1, z1).sqr() * v2->sqr()                 )); }
TYPE Vector3D::angle (PARAM_TO) { return (TYPE)acos((x1    * v2.x  + y1    * v2.y  + z1    * v2.z ) / sqrt(Vector3D(x1, y1, z1).sqr() * v2.sqr()                  )); }
TYPE Vector3D::angle (PARAM_PT) { return (TYPE)acos((v1->x * x2    + v1->y * y2    + v1->z * z2   ) / sqrt(v1->sqr()                  * Vector3D(x2, y2, z2).sqr())); }
TYPE Vector3D::angle (PARAM_PP) { return (TYPE)acos((v1->x * v2->x + v1->y * v2->y + v1->z * v2->z) / sqrt(v1->sqr()                  * v2->sqr()                 )); }
TYPE Vector3D::angle (PARAM_PO) { return (TYPE)acos((v1->x * v2.x  + v1->y * v2.y  + v1->z * v2.z ) / sqrt(v1->sqr()                  * v2.sqr()                  )); }
TYPE Vector3D::angle (PARAM_OT) { return (TYPE)acos((v1.x  * x2    + v1.y  * y2    + v1.z  * z2   ) / sqrt(v1.sqr()                   * Vector3D(x2, y2, z2).sqr())); }
TYPE Vector3D::angle (PARAM_OP) { return (TYPE)acos((v1.x  * v2->x + v1.y  * v2->y + v1.z  * v2->z) / sqrt(v1.sqr()                   * v2->sqr()                 )); }
TYPE Vector3D::angle (PARAM_OO) { return (TYPE)acos((v1.x  * v2.x  + v1.y  * v2.y  + v1.z  * v2.z ) / sqrt(v1.sqr()                   * v2.sqr()                  )); }

// applied with the current instance (no changes will be made)
TYPE Vector3D::angle (PARAM_T) { return (TYPE)acos((this->x * x    + this->y * y    + this->z * z   ) / sqrt(this->sqr() * Vector3D(x, y, z).sqr())); }
TYPE Vector3D::angle (PARAM_P) { return (TYPE)acos((this->x * v->x + this->y * v->y + this->z * v->z) / sqrt(this->sqr() * v->sqr()               )); }
TYPE Vector3D::angle (PARAM_O) { return (TYPE)acos((this->x * v.x  + this->y * v.y  + this->z * v.z ) / sqrt(this->sqr() * v.sqr()                )); }


///////////////////////////////////////////////////
// computes the area of the parallelogram described by the vectors

// returns result using two external vectors
TYPE Vector3D::affineArea (PARAM_TT) { return (TYPE)sqrt(Vector3D(y1    * z2    - z1    * y2,    z1    * x2    - x1    * z2,    x1    * y2    - y1    * x2   ).sqr()); }
TYPE Vector3D::affineArea (PARAM_TP) { return (TYPE)sqrt(Vector3D(y1    * v2->z - z1    * v2->y, z1    * v2->x - x1    * v2->z, x1    * v2->y - y1    * v2->x).sqr()); }
TYPE Vector3D::affineArea (PARAM_TO) { return (TYPE)sqrt(Vector3D(y1    * v2.z  - z1    * v2.y,  z1    * v2.x  - x1    * v2.z,  x1    * v2.y  - y1    * v2.x ).sqr()); }
TYPE Vector3D::affineArea (PARAM_PT) { return (TYPE)sqrt