You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
239 lines
8.0 KiB
C++
239 lines
8.0 KiB
C++
/***************************************************************************
|
|
* Vec4.h *
|
|
* *
|
|
* Basic operations on 4-dimensional vectors. This special case is useful *
|
|
* because many operations are performed inline. *
|
|
* *
|
|
* HISTORY *
|
|
* Name Date Description *
|
|
* *
|
|
* walt 6/26/07 Edited Vec3 to make this new class *
|
|
* arvo 10/27/94 Reorganized (removed Col & Row distinction). *
|
|
* arvo 06/14/93 Initial coding. *
|
|
* *
|
|
*--------------------------------------------------------------------------*
|
|
* Copyright (C) 1994, James Arvo *
|
|
* *
|
|
* This program 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. See http://www.fsf.org/copyleft/gpl.html *
|
|
* *
|
|
* This program is distributed in the hope that it will be useful, but *
|
|
* WITHOUT EXPRESS OR IMPLIED WARRANTY of merchantability or fitness for *
|
|
* any particular purpose. See the GNU General Public License for more *
|
|
* details. *
|
|
* *
|
|
***************************************************************************/
|
|
#ifndef __Vec4_INCLUDED__
|
|
#define __Vec4_INCLUDED__
|
|
|
|
#include <math.h>
|
|
#include <iostream>
|
|
#include "Vec2.h"
|
|
#include "Vec3.h"
|
|
|
|
namespace ArvoMath {
|
|
|
|
class Vec4 {
|
|
public:
|
|
Vec4( float c = 0.0 ) { x = c; y = c; z = c; w = c; }
|
|
Vec4( float a, float b, float c, float d ) { x = a; y = b; z = c; w = d; }
|
|
Vec4( const Vec4 &A ) { x = A.X(); y = A.Y(); z = A.Z(); w = A.W(); }
|
|
Vec4( const Vec3 &A, float d ) { x = A.X(); y = A.Y(); z = A.Z(); w = d; }
|
|
void operator=( float c ) { x = c; y = c; z = c; w = c; }
|
|
void operator=( const Vec4 &A ) { x = A.X(); y = A.Y(); z = A.Z(); w = A.W(); }
|
|
void operator=( const Vec3 &A ) { x = A.X(); y = A.Y(); z = A.Z(); w = 0.0; }
|
|
void operator=( const Vec2 &A ) { x = A.X(); y = A.Y(); z = 0.0; w = 0.0; }
|
|
~Vec4() {}
|
|
float X() const { return x; }
|
|
float Y() const { return y; }
|
|
float Z() const { return z; }
|
|
float W() const { return w; }
|
|
float & X() { return x; }
|
|
float & Y() { return y; }
|
|
float & Z() { return z; }
|
|
float & W() { return w; }
|
|
float operator[]( int i ) const { return *( &x + i ); }
|
|
float & operator[]( int i ) { return *( &x + i ); }
|
|
private:
|
|
float x, y, z, w;
|
|
};
|
|
|
|
//==========================================
|
|
//=== Norm-related functions ===
|
|
//==========================================
|
|
|
|
inline double LenSqr ( const Vec4 &A ) { return Sqr(A[0]) + Sqr(A[1]) + Sqr(A[2]) + Sqr(A[3]); }
|
|
inline double Len ( const Vec4 &A ) { return Sqrt( LenSqr( A ) ); }
|
|
inline double Norm1 ( const Vec4 &A ) { return Abs(A[0]) + Abs(A[1]) + Abs(A[2]) + Abs(A[3]); }
|
|
inline double Norm2 ( const Vec4 &A ) { return Len( A ); }
|
|
inline float SupNorm( const Vec4 &A ) { return MaxAbs( A[0], A[1], A[2], A[3] ); }
|
|
|
|
|
|
//==========================================
|
|
//=== Addition ===
|
|
//==========================================
|
|
|
|
inline Vec4 operator+( const Vec4 &A, const Vec4 &B )
|
|
{
|
|
return Vec4( A.X() + B.X(), A.Y() + B.Y(), A.Z() + B.Z(), A.W() + B.W() );
|
|
}
|
|
|
|
inline Vec4& operator+=( Vec4 &A, const Vec4 &B )
|
|
{
|
|
A.X() += B.X();
|
|
A.Y() += B.Y();
|
|
A.Z() += B.Z();
|
|
A.W() += B.W();
|
|
return A;
|
|
}
|
|
|
|
|
|
//==========================================
|
|
//=== Subtraction ===
|
|
//==========================================
|
|
|
|
inline Vec4 operator-( const Vec4 &A, const Vec4 &B )
|
|
{
|
|
return Vec4( A.X() - B.X(), A.Y() - B.Y(), A.Z() - B.Z(), A.W() - B.W());
|
|
}
|
|
|
|
inline Vec4 operator-( const Vec4 &A )
|
|
{
|
|
return Vec4( -A.X(), -A.Y(), -A.Z(), -A.W() );
|
|
}
|
|
|
|
inline Vec4& operator-=( Vec4 &A, const Vec4 &B )
|
|
{
|
|
A.X() -= B.X();
|
|
A.Y() -= B.Y();
|
|
A.Z() -= B.Z();
|
|
A.W() -= B.W();
|
|
return A;
|
|
}
|
|
|
|
|
|
//==========================================
|
|
//=== Multiplication ===
|
|
//==========================================
|
|
|
|
inline Vec4 operator*( float a, const Vec4 &x )
|
|
{
|
|
return Vec4( a * x.X(), a * x.Y(), a * x.Z(), a * x.W() );
|
|
}
|
|
|
|
inline Vec4 operator*( const Vec4 &x, float a )
|
|
{
|
|
return Vec4( a * x.X(), a * x.Y(), a * x.Z(), a * x.W() );
|
|
}
|
|
|
|
inline float operator*( const Vec4 &A, const Vec4 &B ) // Inner product.
|
|
{
|
|
return A.X() * B.X() + A.Y() * B.Y() + A.Z() * B.Z() + A.W() * B.W();
|
|
}
|
|
|
|
inline Vec4& operator*=( Vec4 &A, float a )
|
|
{
|
|
A.X() *= a;
|
|
A.Y() *= a;
|
|
A.Z() *= a;
|
|
A.W() *= a;
|
|
return A;
|
|
}
|
|
|
|
//==========================================
|
|
//=== Division ===
|
|
//==========================================
|
|
|
|
inline Vec4 operator/( const Vec4 &A, double c )
|
|
{
|
|
double t = 1.0 / c;
|
|
return Vec4( A.X() * t, A.Y() * t, A.Z() * t, A.W() * t);
|
|
}
|
|
|
|
inline Vec4& operator/=( Vec4 &A, double a )
|
|
{
|
|
A.X() /= a;
|
|
A.Y() /= a;
|
|
A.Z() /= a;
|
|
A.W() /= a;
|
|
return A;
|
|
}
|
|
|
|
inline Vec4 operator/( const Vec4 &A, const Vec4 &B ) // Remove component parallel to B.
|
|
{
|
|
Vec4 C; // Cumbersome due to compiler falure.
|
|
double x = LenSqr( B );
|
|
if( x > 0.0 ) C = A - B * (( A * B ) / x); else C = A;
|
|
return C;
|
|
}
|
|
|
|
inline void operator/=( Vec4 &A, const Vec4 &B ) // Remove component parallel to B.
|
|
{
|
|
double x = LenSqr( B );
|
|
if( x > 0.0 ) A -= B * (( A * B ) / x);
|
|
}
|
|
|
|
|
|
//==========================================
|
|
//=== Miscellaneous ===
|
|
//==========================================
|
|
|
|
inline float operator|( const Vec4 &A, const Vec4 &B ) // Inner product.
|
|
{
|
|
return A * B;
|
|
}
|
|
|
|
inline Vec4 Unit( const Vec4 &A )
|
|
{
|
|
double d = LenSqr( A );
|
|
return d > 0.0 ? A / sqrt(d) : Vec4(0,0,0,0);
|
|
}
|
|
|
|
inline Vec4 Unit( float x, float y, float z, float w )
|
|
{
|
|
return Unit( Vec4( x, y, z, w ) );
|
|
}
|
|
|
|
inline Vec4 Ortho( const Vec4 &A, const Vec4 &B )
|
|
{
|
|
return Unit( A / B );
|
|
}
|
|
|
|
inline int operator==( const Vec4 &A, float x )
|
|
{
|
|
return (A[0] == x) && (A[1] == x) && (A[2] == x) && (A[3] == x);
|
|
}
|
|
|
|
// inline Vec4 operator^( const Vec4 &A, const Vec4 &B ) there is no 4ED "cross product" of 2 4D vectors -- we need six dimensions
|
|
|
|
inline double dist( const Vec4 &A, const Vec4 &B )
|
|
{
|
|
return Len( A - B );
|
|
}
|
|
|
|
// inline double Dihedral( const Vec4 &A, const Vec4 &B, const Vec4 &C )
|
|
|
|
inline Vec4 operator>>( const Vec4 &A, const Vec4 &B ) // Project A onto B.
|
|
{
|
|
Vec4 C;
|
|
double x = LenSqr( B );
|
|
if( x > 0.0 ) C = B * (( A * B ) / x);
|
|
return C;
|
|
}
|
|
|
|
inline Vec4 operator<<( const Vec4 &A, const Vec4 &B ) // Project B onto A.
|
|
{
|
|
return B >> A;
|
|
}
|
|
|
|
// inline double Triple( const Vec4 &A, const Vec4 &B, const Vec4 &C )
|
|
|
|
//==========================================
|
|
//=== Output routines ===
|
|
//==========================================
|
|
|
|
extern std::ostream &operator<<( std::ostream &out, const Vec4 & );
|
|
};
|
|
#endif
|