nvidia-texture-tools/src/nvtt/bc7/arvo/Vec2.h
2010-05-29 02:47:57 +00:00

359 lines
10 KiB
C++

/***************************************************************************
* Vec2.h *
* *
* Basic operations on 2-dimensional vectors. This special case is useful *
* because nearly all operations are performed inline. *
* *
* HISTORY *
* Name Date Description *
* *
* arvo 05/22/98 Added TimedVec2, extending Vec2. *
* arvo 06/17/93 Initial coding. *
* *
*--------------------------------------------------------------------------*
* Copyright (C) 1999, 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 __VEC2_INCLUDED__
#define __VEC2_INCLUDED__
#include <math.h>
#include <iostream>
#include "ArvoMath.h"
namespace ArvoMath {
class Vec2; // 2-D floating-point vector.
class TimedVec2; // 2-D vector with a time stamp.
class Mat2x2; // 2x2 floating-point matrix.
class Vec2 {
public:
Vec2( ) { x = 0.0; y = 0.0; }
Vec2( float a, float b ) { x = a; y = b; }
Vec2( const Vec2 &A ) { x = A.X(); y = A.Y(); }
~Vec2() {}
Vec2 &operator=( float s ) { return Set( s, s ); }
Vec2 &operator=( const Vec2 &A ) { return Set( A.X(), A.Y() ); }
float X() const { return x; }
float Y() const { return y; }
float &X() { return x; }
float &Y() { return y; }
float operator[]( int i ) const { return *( &x + i ); }
float &operator[]( int i ) { return *( &x + i ); }
Vec2 &Set( float a, float b ) { x = a; y = b; return *this; }
Vec2 &Set( const Vec2 &A ) { return Set( A.X(), A.Y() ); }
public:
static const Vec2 Zero;
static const Vec2 Xaxis;
static const Vec2 Yaxis;
protected:
float x, y;
};
// This class simply adds a time field to the Vec2 class so that time-stamped
// coordinates can be easily inserted into objects such as Polylines.
class TimedVec2 : public Vec2 {
public:
TimedVec2() { time = 0; }
TimedVec2( const Vec2 &p , long u = 0 ) { Set( p ); time = u; }
TimedVec2( float x, float y, long u = 0 ) { Set(x,y); time = u; }
~TimedVec2() {}
Vec2 &Coord() { return *this; }
Vec2 Coord() const { return *this; }
long Time () const { return time; }
void SetTime( long u ) { time = u; }
protected:
long time;
};
class Mat2x2 {
public:
Mat2x2( ) { Set( 0, 0, 0, 0 ); }
Mat2x2( float a, float b, float c, float d ) { Set( a, b, c, d ); }
Mat2x2( const Vec2 &c1, const Vec2 &c2 );
~Mat2x2( ) {}
Mat2x2 &operator*=( float scale );
Mat2x2 operator* ( float scale ) const;
void Set( float a, float b, float c, float d )
{ m[0][0] = a; m[0][1] = b; m[1][0] = c; m[1][1] = d; }
float operator()( int i, int j ) const { return m[i][j]; }
float &operator()( int i, int j ) { return m[i][j]; }
private:
float m[2][2];
};
//==========================================
//=== Miscellaneous external functions ===
//==========================================
extern float Normalize( Vec2 &A );
extern Vec2 Min ( const Vec2 &A, const Vec2 &B );
extern Vec2 Max ( const Vec2 &A, const Vec2 &B );
//==========================================
//=== Norm-related functions ===
//==========================================
inline double LenSqr ( const Vec2 &A ) { return Sqr(A[0]) + Sqr(A[1]); }
inline double Len ( const Vec2 &A ) { return sqrt( LenSqr( A ) ); }
inline double OneNorm( const Vec2 &A ) { return Abs( A.X() ) + Abs( A.Y() ); }
inline double TwoNorm( const Vec2 &A ) { return Len(A); }
inline float SupNorm( const Vec2 &A ) { return MaxAbs( A.X(), A.Y() ); }
//==========================================
//=== Addition ===
//==========================================
inline Vec2 operator+( const Vec2 &A, const Vec2 &B )
{
return Vec2( A.X() + B.X(), A.Y() + B.Y() );
}
inline Vec2& operator+=( Vec2 &A, const Vec2 &B )
{
A.X() += B.X();
A.Y() += B.Y();
return A;
}
//==========================================
//=== Subtraction ===
//==========================================
inline Vec2 operator-( const Vec2 &A, const Vec2 &B )
{
return Vec2( A.X() - B.X(), A.Y() - B.Y() );
}
inline Vec2 operator-( const Vec2 &A )
{
return Vec2( -A.X(), -A.Y() );
}
inline Vec2& operator-=( Vec2 &A, const Vec2 &B )
{
A.X() -= B.X();
A.Y() -= B.Y();
return A;
}
//==========================================
//=== Multiplication ===
//==========================================
inline Vec2 operator*( float c, const Vec2 &A )
{
return Vec2( c * A.X(), c * A.Y() );
}
inline Vec2 operator*( const Vec2 &A, float c )
{
return Vec2( c * A.X(), c * A.Y() );
}
inline float operator*( const Vec2 &A, const Vec2 &B ) // Inner product
{
return A.X() * B.X() + A.Y() * B.Y();
}
inline Vec2& operator*=( Vec2 &A, float c )
{
A.X() *= c;
A.Y() *= c;
return A;
}
//==========================================
//=== Division ===
//==========================================
inline Vec2 operator/( const Vec2 &A, float c )
{
return Vec2( A.X() / c, A.Y() / c );
}
inline Vec2 operator/( const Vec2 &A, const Vec2 &B )
{
return A - B * (( A * B ) / LenSqr( B ));
}
//==========================================
//=== Comparison ===
//==========================================
inline int operator==( const Vec2 &A, const Vec2 &B )
{
return A.X() == B.X() && A.Y() == B.Y();
}
inline int operator!=( const Vec2 &A, const Vec2 &B )
{
return A.X() != B.X() || A.Y() != B.Y();
}
inline int operator<=( const Vec2 &A, const Vec2 &B )
{
return A.X() <= B.X() && A.Y() <= B.Y();
}
inline int operator<( const Vec2 &A, const Vec2 &B )
{
return A.X() < B.X() && A.Y() < B.Y();
}
inline int operator>=( const Vec2 &A, const Vec2 &B )
{
return A.X() >= B.X() && A.Y() >= B.Y();
}
inline int operator>( const Vec2 &A, const Vec2 &B )
{
return A.X() > B.X() && A.Y() > B.Y();
}
//==========================================
//=== Miscellaneous ===
//==========================================
inline float operator|( const Vec2 &A, const Vec2 &B ) // Inner product
{
return A * B;
}
inline Vec2 Unit( const Vec2 &A )
{
float c = LenSqr( A );
if( c > 0.0 ) c = 1.0 / sqrt( c );
return c * A;
}
inline Vec2 Unit( const Vec2 &A, float &len )
{
float c = LenSqr( A );
if( c > 0.0 )
{
len = sqrt( c );
return A / len;
}
len = 0.0;
return A;
}
inline Vec2 Unit( float x, float y )
{
return Unit( Vec2( x, y ) );
}
inline double dist( const Vec2 &A, const Vec2 &B )
{
return Len( A - B );
}
inline float operator^( const Vec2 &A, const Vec2 &B )
{
return A.X() * B.Y() - A.Y() * B.X();
}
inline int Quadrant( const Vec2 &A )
{
if( A.Y() >= 0.0 ) return A.X() >= 0.0 ? 1 : 2;
return A.X() >= 0.0 ? 4 : 3;
}
inline Vec2 OrthogonalTo( const Vec2 &A ) // A vector orthogonal to that given.
{
return Vec2( -A.Y(), A.X() );
}
inline Vec2 Interpolate( const Vec2 &A, const Vec2 &B, float t )
{
// Compute a point along the segment joining points A and B
// according to the normalized parameter t in [0,1].
return ( 1.0 - t ) * A + t * B;
}
//==========================================
//=== Operations involving Matrices ===
//==========================================
inline Mat2x2 Outer( const Vec2 &A, const Vec2 &B ) // Outer product.
{
Mat2x2 C;
C(0,0) = A.X() * B.X();
C(0,1) = A.X() * B.Y();
C(1,0) = A.Y() * B.X();
C(1,1) = A.Y() * B.Y();
return C;
}
inline Vec2 operator*( const Mat2x2 &M, const Vec2 &A )
{
return Vec2(
M(0,0) * A.X() + M(0,1) * A.Y(),
M(1,0) * A.X() + M(1,1) * A.Y()
);
}
inline Mat2x2 &Mat2x2::operator*=( float scale )
{
m[0][0] *= scale;
m[0][1] *= scale;
m[1][0] *= scale;
m[1][1] *= scale;
return *this;
}
inline Mat2x2 Mat2x2::operator*( float scale ) const
{
return Mat2x2(
scale * m[0][0], scale * m[0][1],
scale * m[1][0], scale * m[1][1]
);
}
inline Mat2x2 operator*( float scale, const Mat2x2 &M )
{
return M * scale;
}
inline float Norm1( const Mat2x2 &A )
{
return Max( Abs(A(0,0)) + Abs(A(0,1)), Abs(A(1,0)) + Abs(A(1,1)) );
}
inline double det( const Mat2x2 &A )
{
return A(0,0) * A(1,1) - A(1,0) * A(0,1);
}
extern Vec2 Solve( // Return solution x of the system Ax = b.
const Mat2x2 &A,
const Vec2 &b
);
//==========================================
//=== Output routines ===
//==========================================
extern std::ostream &operator<<( std::ostream &out, const Vec2 & );
extern std::ostream &operator<<( std::ostream &out, const Mat2x2 & );
};
#endif