% MotionGenesis file: TetrahedronVolume.r
% Copyright (c) 2025-2026 Motion Genesis LLC.  All rights reserved.
%----------------------------------------------------------------------------
%TetrahedronVolume
%TetrahedronVolume
%
% Purpose:  Calculates a tetraedron's volume using position vectors from
%           a point P to various vertices on the tetrahedron.
%
%Syntax 1:  TetrahedronVolume( p0>, p1>, p2>, p3> )
%Syntax 2:  TetrahedronVolume( p1>, p2>, p3> )
%
%   Input:  p0> -- position vector from point P to vertex 0.
%           p1> -- position vector from point P to vertex 1.
%           p2> -- position vector from point P to vertex 2.
%           p3> -- position vector from point P to vertex 3.
%
%Output 1:  The tetrahedron's volume (which may be negative, zero or positive).
%	    The negative, zero, or positive sign is based on the cross-products
%           in the underlying 3-argument calculation, namely:
%	    TetahedronVolume( p1> - p0>,  p2> - p0>,  p3> - p0> )
%
%Output 2:  The tetrahedron's volume (assumes point P is vertex 0).
%	    Volume is negative if Dot( Cross(p1>, p2>), p3>) < 0,
%	    Volume is zero     if Dot( Cross(p1>, p2>), p3>) = 0,
%	    Volume is positive if Dot( Cross(p1>, p2>), p3>) > 0,
%
% Related:  SetMass          GetMass         SetInertia
%           GetCmPosition    GetCmVelocity   GetCmAcceleration
%           GetInertiaDyadic  GetInertiaMatrix  GetMomentOfInertia
%           GetProductOfInertia  GetRadiusOfGyration  GetInertiaVector
%	    TriangleArea       TriangleCMPosition     TriangleInertiaAboutVertex0
%	    TetrahedronVolume  TetrahedronCMPosition  TetrahedronInertiaAboutVertex0
%----------------------------------------------------------------------------
IF(     #NUM_ARGS# < 3 )  { echo("\n\a\kError: The command TetrahedronVolume has too few arguments.") }
ELSEIF( #NUM_ARGS# > 4 )  { echo("\n\a\kError: The command TetrahedronVolume has too many arguments.") }
ELSEIF( #NUM_ARGS# == 4 ) 
{ 
   (Dot( TriangleArea(#2#, #3#), #4# - #1#) )/3
%  TetrahedronVolume(#2# - #1#, #3# - #1#, #4# - #1#)   % Less efficient version.
}
ELSE 
{ 
   Dot( Cross(#1#, #2#), #3#)/6 
}
% end of file
