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.
120 lines
4.8 KiB
C++
120 lines
4.8 KiB
C++
/***************************************************************************
|
|
* Vec3.C *
|
|
* *
|
|
* Basic operations on 3-dimensional vectors. This special case is useful *
|
|
* because many operations are performed inline. *
|
|
* *
|
|
* HISTORY *
|
|
* Name Date Description *
|
|
* *
|
|
* 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. *
|
|
* *
|
|
***************************************************************************/
|
|
#include <stdio.h>
|
|
#include <math.h>
|
|
#include "ArvoMath.h"
|
|
#include "Vec3.h"
|
|
#include "form.h"
|
|
|
|
namespace ArvoMath {
|
|
|
|
float Normalize( Vec3 &A )
|
|
{
|
|
float d = Len( A );
|
|
if( d > 0.0 )
|
|
{
|
|
double c = 1.0 / d;
|
|
A.X() *= c;
|
|
A.Y() *= c;
|
|
A.Z() *= c;
|
|
}
|
|
return( d );
|
|
}
|
|
|
|
double Angle( const Vec3 &A, const Vec3 &B )
|
|
{
|
|
double t = LenSqr(A) * LenSqr(B);
|
|
if( t <= 0.0 ) return 0.0;
|
|
return ArcCos( (A * B) / sqrt(t) );
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*
|
|
* O R T H O N O R M A L *
|
|
* *
|
|
* On Input A, B....: Two linearly independent 3-space vectors. *
|
|
* *
|
|
* On Return A.......: Unit vector pointing in original A direction. *
|
|
* B.......: Unit vector orthogonal to A and in subspace spanned *
|
|
* by original A and B vectors. *
|
|
* C.......: Unit vector orthogonal to both A and B, chosen so *
|
|
* that A-B-C forms a right-handed coordinate system. *
|
|
* *
|
|
*-------------------------------------------------------------------------*/
|
|
int Orthonormal( Vec3 &A, Vec3 &B, Vec3 &C )
|
|
{
|
|
if( Normalize( A ) == 0.0 ) return 1;
|
|
B /= A;
|
|
if( Normalize( B ) == 0.0 ) return 1;
|
|
C = A ^ B;
|
|
return 0;
|
|
}
|
|
|
|
int Orthonormal( Vec3 &A, Vec3 &B )
|
|
{
|
|
if( Normalize( A ) == 0.0 ) return 1;
|
|
B /= A;
|
|
if( Normalize( B ) == 0.0 ) return 1;
|
|
return 0;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------*
|
|
* O R T H O G O N A L T O *
|
|
* *
|
|
* Returns a vector that is orthogonal to A (but of arbitrary length). *
|
|
* *
|
|
*-------------------------------------------------------------------------*/
|
|
Vec3 OrthogonalTo( const Vec3 &A )
|
|
{
|
|
float c = 0.5 * SupNorm( A );
|
|
if( c == 0.0 ) return Vec3( 1.0, 0.0, 0.0 );
|
|
if( c <= Abs(A.X()) ) return Vec3( -A.Y(), A.X(), 0.0 );
|
|
if( c <= Abs(A.Y()) ) return Vec3( 0.0, -A.Z(), A.Y() );
|
|
return Vec3( A.Z(), 0.0, -A.X() );
|
|
}
|
|
|
|
Vec3 Min( const Vec3 &A, const Vec3 &B )
|
|
{
|
|
return Vec3(
|
|
Min( A.X(), B.X() ),
|
|
Min( A.Y(), B.Y() ),
|
|
Min( A.Z(), B.Z() ));
|
|
}
|
|
|
|
Vec3 Max( const Vec3 &A, const Vec3 &B )
|
|
{
|
|
return Vec3(
|
|
Max( A.X(), B.X() ),
|
|
Max( A.Y(), B.Y() ),
|
|
Max( A.Z(), B.Z() ));
|
|
}
|
|
|
|
std::ostream &operator<<( std::ostream &out, const Vec3 &A )
|
|
{
|
|
out << form( " %9.5f %9.5f %9.5f", A.X(), A.Y(), A.Z() ) << std::endl;
|
|
return out;
|
|
}
|
|
};
|