povray/source/backend/math/vector.h
2013-11-06 13:07:19 -05:00

419 lines
9.1 KiB
C++

/*******************************************************************************
* vector.h
*
* This module contains macros to perform operations on vectors.
*
* ---------------------------------------------------------------------------
* Persistence of Vision Ray Tracer ('POV-Ray') version 3.7.
* Copyright 1991-2013 Persistence of Vision Raytracer Pty. Ltd.
*
* POV-Ray is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* POV-Ray 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* ---------------------------------------------------------------------------
* POV-Ray is based on the popular DKB raytracer version 2.12.
* DKBTrace was originally written by David K. Buck.
* DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
* ---------------------------------------------------------------------------
* $File: //depot/public/povray/3.x/source/backend/math/vector.h $
* $Revision: #1 $
* $Change: 6069 $
* $DateTime: 2013/11/06 11:59:40 $
* $Author: chrisc $
*******************************************************************************/
#ifndef VECTOR_H
#define VECTOR_H
#include "backend/frame.h"
namespace pov
{
/*****************************************************************************
* Inline functions
******************************************************************************/
// Vector Add
inline void VAdd(VECTOR a, const VECTOR b, const VECTOR c)
{
a[X] = b[X] + c[X];
a[Y] = b[Y] + c[Y];
a[Z] = b[Z] + c[Z];
}
inline void VAdd(SNGL_VECT a, const VECTOR b, const VECTOR c)
{
a[X] = b[X] + c[X];
a[Y] = b[Y] + c[Y];
a[Z] = b[Z] + c[Z];
}
inline void VAdd(SNGL_VECT a, const SNGL_VECT b, const SNGL_VECT c)
{
a[X] = b[X] + c[X];
a[Y] = b[Y] + c[Y];
a[Z] = b[Z] + c[Z];
}
inline void VAddEq(VECTOR a, const VECTOR b)
{
a[X] += b[X];
a[Y] += b[Y];
a[Z] += b[Z];
}
inline void VAddEq(SNGL_VECT a, const VECTOR b)
{
a[X] += b[X];
a[Y] += b[Y];
a[Z] += b[Z];
}
inline void VAddEq(SNGL_VECT a, const SNGL_VECT b)
{
a[X] += b[X];
a[Y] += b[Y];
a[Z] += b[Z];
}
// Vector Subtract
inline void VSub(VECTOR a, const VECTOR b, const VECTOR c)
{
a[X] = b[X] - c[X];
a[Y] = b[Y] - c[Y];
a[Z] = b[Z] - c[Z];
}
inline void VSub(SNGL_VECT a, const VECTOR b, const VECTOR c)
{
a[X] = b[X] - c[X];
a[Y] = b[Y] - c[Y];
a[Z] = b[Z] - c[Z];
}
inline void VSub(VECTOR a, const SNGL_VECT b, const VECTOR c)
{
a[X] = b[X] - c[X];
a[Y] = b[Y] - c[Y];
a[Z] = b[Z] - c[Z];
}
inline void VSub(VECTOR a, const VECTOR b, const SNGL_VECT c)
{
a[X] = b[X] - c[X];
a[Y] = b[Y] - c[Y];
a[Z] = b[Z] - c[Z];
}
inline void VSub(VECTOR a, const SNGL_VECT b, const SNGL_VECT c)
{
a[X] = b[X] - c[X];
a[Y] = b[Y] - c[Y];
a[Z] = b[Z] - c[Z];
}
inline void VSub(SNGL_VECT a, const SNGL_VECT b, const SNGL_VECT c)
{
a[X] = b[X] - c[X];
a[Y] = b[Y] - c[Y];
a[Z] = b[Z] - c[Z];
}
inline void VSubEq(VECTOR a, const VECTOR b)
{
a[X] -= b[X];
a[Y] -= b[Y];
a[Z] -= b[Z];
}
inline void VSubEq(SNGL_VECT a, const VECTOR b)
{
a[X] -= b[X];
a[Y] -= b[Y];
a[Z] -= b[Z];
}
inline void VSubEq(SNGL_VECT a, const SNGL_VECT b)
{
a[X] -= b[X];
a[Y] -= b[Y];
a[Z] -= b[Z];
}
// Scale - Multiply Vector by a Scalar
inline void VScale(VECTOR a, const VECTOR b, DBL k)
{
a[X] = b[X] * k;
a[Y] = b[Y] * k;
a[Z] = b[Z] * k;
}
// Scale - Multiply Vector by a Scalar
inline void VScale(SNGL_VECT a, const VECTOR b, DBL k)
{
a[X] = b[X] * k;
a[Y] = b[Y] * k;
a[Z] = b[Z] * k;
}
inline void VScale(SNGL_VECT a, const SNGL_VECT b, SNGL k)
{
a[X] = b[X] * k;
a[Y] = b[Y] * k;
a[Z] = b[Z] * k;
}
inline void VScaleEq(VECTOR a, DBL k)
{
a[X] *= k;
a[Y] *= k;
a[Z] *= k;
}
inline void VScaleEq(SNGL_VECT a, SNGL k)
{
a[X] *= k;
a[Y] *= k;
a[Z] *= k;
}
// Inverse Scale - Divide Vector by a Scalar
inline void VInverseScale(VECTOR a, const VECTOR b, DBL k)
{
DBL tmp = 1.0 / k;
a[X] = b[X] * tmp;
a[Y] = b[Y] * tmp;
a[Z] = b[Z] * tmp;
}
inline void VInverseScale(SNGL_VECT a, const SNGL_VECT b, SNGL k)
{
SNGL tmp = 1.0 / k;
a[X] = b[X] * tmp;
a[Y] = b[Y] * tmp;
a[Z] = b[Z] * tmp;
}
inline void VInverseScaleEq(VECTOR a, DBL k)
{
DBL tmp = 1.0 / k;
a[X] *= tmp;
a[Y] *= tmp;
a[Z] *= tmp;
}
inline void VInverseScaleEq(SNGL_VECT a, SNGL k)
{
SNGL tmp = 1.0 / k;
a[X] *= tmp;
a[Y] *= tmp;
a[Z] *= tmp;
}
// Dot Product - Gives Scalar angle (a) between two vectors (b) and (c)
inline void VDot(DBL& a, const VECTOR b, const VECTOR c)
{
a = b[X] * c[X] + b[Y] * c[Y] + b[Z] * c[Z];
}
inline void VDot(SNGL& a, const VECTOR b, const VECTOR c)
{
a = b[X] * c[X] + b[Y] * c[Y] + b[Z] * c[Z];
}
inline void VDot(DBL& a, const VECTOR b, const SNGL_VECT c)
{
a = b[X] * c[X] + b[Y] * c[Y] + b[Z] * c[Z];
}
inline void VDot(DBL& a, const SNGL_VECT b, const VECTOR c)
{
a = b[X] * c[X] + b[Y] * c[Y] + b[Z] * c[Z];
}
inline void VDot(DBL& a, const SNGL_VECT b, const SNGL_VECT c)
{
a = b[X] * c[X] + b[Y] * c[Y] + b[Z] * c[Z];
}
inline void VDot(SNGL& a, const SNGL_VECT b, const SNGL_VECT c)
{
a = b[X] * c[X] + b[Y] * c[Y] + b[Z] * c[Z];
}
// Cross Product - returns Vector (a) = (b) x (c)
inline void VCross(VECTOR a, const VECTOR b, const VECTOR c)
{
VECTOR tmp;
tmp[X] = b[Y] * c[Z] - b[Z] * c[Y];
tmp[Y] = b[Z] * c[X] - b[X] * c[Z];
tmp[Z] = b[X] * c[Y] - b[Y] * c[X];
Assign_Vector(a, tmp);
}
// Evaluate - returns Vector (a) = Multiply Vector (b) by Vector (c)
inline void VEvaluate(VECTOR a, const VECTOR b, const VECTOR c)
{
a[X] = b[X] * c[X];
a[Y] = b[Y] * c[Y];
a[Z] = b[Z] * c[Z];
}
inline void VEvaluateEq(VECTOR a, const VECTOR b)
{
a[X] *= b[X];
a[Y] *= b[Y];
a[Z] *= b[Z];
}
// Divide - returns Vector (a) = Divide Vector (a) by Vector (b)
inline void VDivEq(VECTOR a, const VECTOR b)
{
a[X] /= b[X];
a[Y] /= b[Y];
a[Z] /= b[Z];
}
// Simple Scalar Square Macro
inline DBL Sqr(DBL a)
{
return a * a;
}
inline SNGL Sqr(SNGL a)
{
return a * a;
}
// Vector Length - returs Scalar Euclidean Length (a) of Vector (b)
inline void VLength(DBL& a, const VECTOR b)
{
a = sqrt(b[X] * b[X] + b[Y] * b[Y] + b[Z] * b[Z]);
}
inline void VLength(SNGL& a, const SNGL_VECT b)
{
a = sqrt(b[X] * b[X] + b[Y] * b[Y] + b[Z] * b[Z]);
}
// Vector Distance - returs Scalar Euclidean Distance (a) between two points/Vectors (b) and (c)
inline void VDist(DBL& a, const VECTOR b, const VECTOR c)
{
VECTOR tmp;
VSub(tmp, b, c);
VLength(a, tmp);
}
// Normalize a Vector - returns a vector (length of 1) that points at (b)
inline void VNormalize(VECTOR a, const VECTOR b)
{
DBL tmp;
VLength(tmp, b);
VInverseScale(a, b, tmp);
}
inline void VNormalize(SNGL_VECT a, const SNGL_VECT b)
{
SNGL tmp;
VLength(tmp, b);
VInverseScale(a, b, tmp);
}
inline void VNormalizeEq(VECTOR a)
{
DBL tmp;
VLength(tmp, a);
VInverseScaleEq(a, tmp);
}
// Compute a Vector (a) Halfway Between Two Given Vectors (b) and (c)
inline void VHalf(VECTOR a, const VECTOR b, const VECTOR c)
{
a[X] = 0.5 * (b[X] + c[X]);
a[Y] = 0.5 * (b[Y] + c[Y]);
a[Z] = 0.5 * (b[Z] + c[Z]);
}
// Calculate the sum of the sqares of the components of a vector. (the square of its length)
inline DBL VSumSqr(const VECTOR a)
{
return a[X] * a[X] + a[Y] * a[Y] + a[Z] * a[Z];
}
// Linear combination of 2 vectors. [DB 7/94]
// v = k1 * v1 + k2 * v2
inline void VLinComb2(VECTOR v, DBL k1, const VECTOR v1, DBL k2, const VECTOR v2)
{
v[X] = k1 * v1[X] + k2 * v2[X];
v[Y] = k1 * v1[Y] + k2 * v2[Y];
v[Z] = k1 * v1[Z] + k2 * v2[Z];
}
// Linear combination of 3 vectors. [DB 7/94]
// v = k1 * v1 + k2 * v2 + k3 * v3
inline void VLinComb3(VECTOR v, DBL k1, const VECTOR v1, DBL k2, const VECTOR v2, DBL k3, const VECTOR v3)
{
v[X] = k1 * v1[X] + k2 * v2[X] + k3 * v3[X];
v[Y] = k1 * v1[Y] + k2 * v2[Y] + k3 * v3[Y];
v[Z] = k1 * v1[Z] + k2 * v2[Z] + k3 * v3[Z];
}
// Evaluate a ray equation. [DB 7/94]
// IPoint = Origin + depth * Direction
inline void VEvaluateRay(VECTOR IPoint, const VECTOR Origin, DBL depth, const VECTOR Direction)
{
IPoint[X] = Origin[X] + depth * Direction[X];
IPoint[Y] = Origin[Y] + depth * Direction[Y];
IPoint[Z] = Origin[Z] + depth * Direction[Z];
}
// Add a scaled vector. [DB 7/94]
// v = v1 + k * v2;
// v += k * v2;
inline void VAddScaled(VECTOR v, const VECTOR v1, DBL k, const VECTOR v2)
{
v[X] = v1[X] + k * v2[X];
v[Y] = v1[Y] + k * v2[Y];
v[Z] = v1[Z] + k * v2[Z];
}
inline void VAddScaledEq(VECTOR v, DBL k, const VECTOR v2)
{
v[X] += k * v2[X];
v[Y] += k * v2[Y];
v[Z] += k * v2[Z];
}
// Inverse Scale - Divide Vector by a Scalar
inline void V4D_InverseScaleEq(VECTOR_4D a, DBL k)
{
DBL tmp = 1.0 / k;
a[X] *= tmp;
a[Y] *= tmp;
a[Z] *= tmp;
a[T] *= tmp;
}
// Dot Product - Gives Scalar angle (a) between two vectors (b) and (c)
inline void V4D_Dot(DBL& a, const VECTOR_4D b, const VECTOR_4D c)
{
a = b[X] * c[X] + b[Y] * c[Y] + b[Z] * c[Z] + b[T] * c[T];
}
}
#endif