//////////////////////////////////////////////////////////////////////////////////////
// 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.z; return 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.z; return 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.z; return 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.z; return 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