/*************************************************************************** * 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 #include #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; } };