Skip to content
Snippets Groups Projects
tfm.pl 36.89 KiB
#! /usr/bin/perl

# Perl geometry calculator, with special assistance for astronomical coordinates.
# By Stuart Levy, NCSA, University of Illinois, 1997-2006.  slevy@ncsa.uiuc.edu.
#
# $Id$

$pi = 3.14159265358979323846;
$choplimit = 2e-14;
&init_eq2gal;

sub help {
  print STDERR <<EOF;
Usage for some tfm.pl functions:
Here "T" is a 4x4 matrix as list of 16 numbers
     "v" is a vector (arbitrary length unless specified)
     "q" is a 4-component quaternion, real-part (cos theta/2) first
  tfm(ax,ay,az, angle)=>T  4x4 rot about axis (ax,ay,az) by angle (degrees)
  tfm(tx,ty,tz)	      =>T  4x4 translation
  tfm(s)              =>T  4x4 uniform scaling
  tfm("scale",sx,sy,sz)=>T 4x4 nonuniform scaling
  tfm(ax,ay,az, angle, cx,cy,cz)  4x4 rot about axis, fixing center cx,cy,cz
  transpose( T )	   NxN matrix transpose
  tmul( T1, T2 ) => T1*T2  4x4 (or 3x3) matrix product
  eucinv( T ) => Tinverse  4x4 inverse (assuming T Euclidean rot/trans/uniform scale)
  hls2rgb(h,l,s) => (r,g,b) color conversion
  svmul( s, v ) => s*v	   scalar * vector
  vmmul( v4, T ) => v'	   4-vector * 4x4 matrix => 4-vector
  v3mmul( v3, T ) => v3'   3-D point * (3x3 or 4x4) matrix => 3-D point
  vsub( va, vb ) => va-vb  vector subtraction
  vsadd(s,va, vb) => s*va+vb  vector scaling & addition
  lerp( t, va, vb ) => v   linear interpolation from va to vb: (1-t)*va + t*vb
  dot( va, vb ) => va.vb   dot product
  mag( v )      => |v|     length of vector v
  normalize( v ) => v/|v|  vector v, scaled to unit length (or zero length)
  t2quat( T ) => q	   extract rotation-part of 4x4 T into quaternion
  quat2t( q ) => T	   quaternion to 4x4 matrix T
  quatmul(qa, qb) => qa*qb quaternion multiplication
  qrotbtwn(v3a, v3b) => q  quaternion which rotates 3-vector va into vb
  lookat(from3,to3,up3,roll) construct 4x4 camera->world c2w matrix (pc * c2w = pw).
  t2euler(\"xzy\",T) => X,Z,Y (deg) so rotY*rotZ*rotX = T.  t2euler(\"yxz\",T) = t2aer(T).
  t2meuler(\"yzx\",T) = X,Y,Z, using t2euler(\"xzy\",T).  meuler2t(\"yzx\",X,Y,Z)
  euler2quat(\"xzy\",X,Z,Y) => q;  quat2euler(\"xzy\", q) => angleX,Z,Y, so rotY*rotZ*rotX = q.
  meuler2quat(\"yzx\",X,Y,Z) => q; quat2meuler(\"yzx\",q) => angleX,Y,Z
  aer2t(Ry,Rx,Rz) => T     and  t2aer(T) => Ry,Rx,Rz  Euler angle conversions
  vd2tfm(x,y,z,Rx,Ry,Rz)   and  tfm2vd(T)  4x4 matrix <=> VirDir tx ty tz rx ry rz
  eq2dms(v3) => text "hh:mm.m +dd:mm:ss dist"
  radec2eq(ra,dec,dist)    (ra h:m:s, dec d:m:s, dist) => J2000 3-vector
  radec2eqbasis(ra,dec) => 3x3matrix (ra,dec DEGREES -> XY=sky-plane, +Ynorth)
  Tprecess(fromyr,toyr) => 3x3matrix: Pfrom * Tprecess(fromyear,toyear) = Pto
  \@Tab = 3x3matrix; a,b are: g(alactic) s(upergalactic) e(qJ2000) z(ecliptic) c(C-gal)
  stats( [svar,] val1, ... ) => ( svar, N, mean, SD )  (SD = sqrt(ssq/N))
  list("string")	   converts blank/comma/brace-separated string to list
  put( list )		   print N-vector, or 2x2 or 3x3 or 4x4 matrix
  pt( list )		   print list on one line, full precision (for copy/pasting)
Each inputline is a perl "eval", e.g.: \@a = (1,2,3); print dot(\@a,\@a); sub me {...}
Previous line's answer saved in "\@_"; first scalar saved in \"\$_\".
For multiline input, have a not-yet-closed "{", or use "\\" at end of line.
EOF
  
}

# &smoothstep(t [,vmin,vmax [,tmin,tmax]] )
sub smoothstep {
   local($t, $vmin, $vmax, $tmin, $tmax) = @_;
   $vmin = 0 unless defined($vmin);
   $vmax = 1 unless defined($vmax);
   $t = ($t-$tmin) / ($tmax-$tmin) if $tmax != $tmin;
   return $vmin if($t <= 0);
   return $vmax if($t >= 1);