Metropoli BBS
VIEWER: math.inc MODE: TEXT (ASCII)
/* ************************************************************************
   *									  *
   *		       	    Mathematical Functions                        *
   *									  *
   *		 Original Material by Christopher D. Watkins		  *
   *									  *
   *			     'C' conversion by				  *
   *                            Larry Sharp				  *
   *									  *
   ************************************************************************

   Radians   - converts degrees to radians
   Degrees   - converts radians to degrees
   CosD	     - cosine in degrees
   SinD	     - sine in degrees
   Power     - power a^n
   Log       - log base 10
   Exp10     - exp base 10
   Sign      - negative=-1  positive=1  null=0
   IntSign   - negative=-1  positive=1  null=0
   IntSqrt   - integer square root
   IntPower  - integer power a^n
*/

#define Ln10 2.30258509299405E+000
#define Pi 3.1415927
#define PiOver180 1.74532925199433E-002
#define PiUnder180 5.72957795130823E+001

typedef enum {false, true} Boolean;
typedef unsigned char      Byte;
typedef unsigned int       Word;


int Round(float x)
{
  return((int)(x+0.5));
}

int Trunc(float x)
{
  return((int)(x));
}

float SqrFP(float x)
{
  return(x*x);
}

int Sqr(int x)
{
  return(x*x);
}

float Radians(float Angle)
{
  return(Angle*PiOver180);
}

float Degrees(float Angle)
{
  return(Angle*PiUnder180);
}

float CosD(float Angle)
{
  return(cos(Radians(Angle)));
}

float SinD(float Angle)
{
  return(sin(Radians(Angle)));
}

float Power(float Base, int Exponent)
{
  float BPower;
  int   t;

  if(Exponent==0)
    return(1);
  else
  {
    BPower=1.0;
    for(t=1; t<=Exponent; t++)
    {
      BPower*=Base;
    }
    return(BPower);
  }
}

float Log(float x)
{
  return(log(x)/Ln10);
}

float Exp10(float x)
{
  return(exp(x*Ln10));
}

float Sign(float x)
{
  if(x<0)
    return(-1);
  else
  {
    if(x>0)
      return(1);
    else
    {
      return(0);
    }
  }
}

int IntSign(int x)
{
  if(x<0)
    return(-1);
  else
  {
    if(x>0)
      return(1);
    else
    {
      return(0);
    }
  }
}

int IntSqrt(int x)
{
  int OddInt, OldArg, FirstSqrt;

  OddInt=1;
  OldArg=x;
  while(x>=0)
  {
    x-=OddInt;
    OddInt+=2;
  }
  FirstSqrt=OddInt >> 1;
  if(Sqr(FirstSqrt)-FirstSqrt+1 > OldArg)
    return(FirstSqrt-1);
  else
    return(FirstSqrt);
}

int IntPower(int Base, int Exponent)
{
  if(Exponent==0)
    return(1);
  else
    return(Base*IntPower(Base, Exponent-1));
}

/* ***********************************************************************
   *									 *
   *			Vector And Matrix Routines			 *
   *									 *
   ***********************************************************************

   Vec             - Make Vector
   VecInt	   - Make Integer Vector
   UnVec	   - Get Components of vector
   UnVecInt	   - Get Components of Integer Vector
   VecDot	   - Vector Dot Product
   VecCross	   - Vector Cross Product
   VecLen	   - Vector Length
   VecNormalize	   - Vector Normalize
   VecMatxMult	   - Vector Matrix Multiply
   VecSub	   - Vector Subtraction
   VecSubInt	   - Vector Subtraction Integer
   VecAdd	   - Vector Addition
   VecAdd3	   - Vector Addition
   VecCopy	   - Vector Copy
   VecLinComb	   - Vector Linear Combination
   VecScalMult	   - Vector Scalar Multiple
   VecScalMultI    - Vector Scalar Multiple
   VecScalMultInt  - Vector Scalar Multiple and Rounding
   VecAddScalMult  - Vector Add Scalar Multiple
   VecNull	   - Vector Null
   VecNullInt	   - Vector Null Integer
   VecElemMult	   - Vector Element Multiply
*/

typedef float TDA[3];
typedef int   TDIA[3];
typedef float FDA[4];
typedef float Matx4x4[4][4];

void Vec(float r, float s, float t, TDA A)
{
  A[0]=r;
  A[1]=s;
  A[2]=t;
}

void VecInt(int r, int s, int t, TDIA A)
{
  A[0]=r;
  A[1]=s;
  A[2]=t;
}

void UnVec(TDA A, float *r, float *s, float *t)
{
  *r=A[0];
  *s=A[1];
  *t=A[2];
}

void UnVecInt(TDIA A, int *r, int *s, int *t)
{
  *r=A[0];
  *s=A[1];
  *t=A[2];
}

float VecDot(TDA A, TDA B)
{
  return(A[0]*B[0] + A[1]*B[1] + A[2]*B[2]);
}

void VecCross(TDA A, TDA B, TDA C)
{
  C[0]=A[1]*B[2] - A[2]*B[1];
  C[1]=A[2]*B[0] - A[0]*B[2];
  C[2]=A[0]*B[1] - A[1]*B[0];
}

float VecLen(TDA A)
{
  return(sqrt(SqrFP(A[0])+SqrFP(A[1])+SqrFP(A[2])));
}

void VecNormalize(TDA A)
{
  float dist, invdist;

  dist=VecLen(A);
  if(!(dist==0.0))
  {
    invdist=1/dist;
    A[0]*=invdist;
    A[1]*=invdist;
    A[2]*=invdist;
  }
  else
  {
    puts("Zero-Length Vectors cannot be Normalized");
    exit(1);
  }
}

void VecMatxMult(FDA A, Matx4x4 Matrix, FDA B)
{
  int mRow, mCol;

  for(mCol=0; mCol<4; mCol++)
  {
    B[mCol]=0;
    for(mRow=0; mRow<4; mRow++)
      B[mCol]+=A[mRow]*Matrix[mRow][mCol];
  }
}

void VecSub(TDA A, TDA B, TDA C)
{
  C[0]=A[0]-B[0];
  C[1]=A[1]-B[1];
  C[2]=A[2]-B[2];
}

void VecSubInt(TDIA A, TDIA B, TDA C)
{
  C[0]=A[0]-B[0];
  C[1]=A[1]-B[1];
  C[2]=A[2]-B[2];
}

void VecAdd(TDA A, TDA B, TDA C)
{
  C[0]=A[0]+B[0];
  C[1]=A[1]+B[1];
  C[2]=A[2]+B[2];
}

void VecAdd3(TDA A, TDA B, TDA C, TDA D)
{
  D[0]=A[0]+B[0]+C[0];
  D[1]=A[1]+B[1]+C[1];
  D[2]=A[2]+B[2]+C[2];
}

void VecCopy(TDA A, TDA B)
{
  int i;
  for(i=0; i<3; i++)
  {
    B[i]=A[i];
  }
}

void VecLinComb(float r, TDA A, float s, TDA B, TDA C)
{
  C[0]=r*A[0]+s*B[0];
  C[1]=r*A[1]+s*B[1];
  C[2]=r*A[2]+s*B[2];
}

void VecScalMult(float r, TDA A, TDA B)
{
  B[0]=r*A[0];
  B[1]=r*A[1];
  B[2]=r*A[2];
}

void VecScalMultI(float r, TDIA A, TDA B)
{
  B[0]=r*A[0];
  B[1]=r*A[1];
  B[2]=r*A[2];
}

void VecScalMultInt(float r, TDA A, TDIA B)
{
  B[0]=Round(r*A[0]);
  B[1]=Round(r*A[1]);
  B[2]=Round(r*A[2]);
}

void VecAddScalMult(float r, TDA A, TDA B, TDA C)
{
  C[0]=r*A[0]+B[0];
  C[1]=r*A[1]+B[1];
  C[2]=r*A[2]+B[2];
}

void VecNull(TDA A)
{
  A[0]=0.0;
  A[1]=0.0;
  A[2]=0.0;
}

void VecNullInt(TDIA A)
{
  A[0]=0;
  A[1]=0;
  A[2]=0;
}

void VecElemMult(float r, TDA A, TDA B, TDA C)
{
  C[0]=r*A[0]*B[0];
  C[1]=r*A[1]*B[1];
  C[2]=r*A[2]*B[2];
}

/* ***********************************************************************
   *									 *
   *			Affine Transformation Routines			 *
   *									 *
   ***********************************************************************

   ZeroMatrix		- zeros the elements of a 4x4 matrix
   Translate3D		- make translation matrix
   Scale3D		- make scaling matrix
   Rotate3D		- make rotation matrix
   ZeroAllMatricies	- zeros all matricies used in transformation
   Multiply3DMatricies	- multiply 2 4x4 matricies
   PrepareMatrix	- prepare the transformation matrix (Tm=S*R*T)
   PrepareInvMatrix	- prepare the inverse transformation matrix
   Transform		- multipy a vertex by the transformation matrix
*/

void ZeroMatrix(Matx4x4 A)
{
  int i,j;

  for(i=0; i<4; i++)
  {
    for(j=0; j<4; j++)
      A[i][j]=0.0;
  }
}

void Translate3D(float tx, float ty, float tz, Matx4x4 A)
{
  int i;

  ZeroMatrix(A);
  for(i=0; i<4; i++)
    A[i][i]=1.0;
  A[0][3]=-tx;
  A[1][3]=-ty;
  A[2][3]=-tz;
}

void Scale3D(float sx, float sy, float sz, Matx4x4 A)
{
  ZeroMatrix(A);
  A[0][0]=sx;
  A[1][1]=sy;
  A[2][2]=sz;
  A[3][3]=1.0;
}

void Rotate3D(int m, float Theta, Matx4x4 A)
{
  int   m1,m2;
  float c,s;

  ZeroMatrix(A);
  A[m-1][m-1]=1.0;
  A[3][3]=1.0;
  m1=(m % 3)+1;
  m2=(m1 % 3);
  m1-=1;
  c=CosD(Theta);
  s=SinD(Theta);
  A[m1][m1]=c;
  A[m1][m2]=s;
  A[m2][m2]=c;
  A[m2][m1]=-s;
}

void Multiply3DMatricies(Matx4x4 A, Matx4x4 B, Matx4x4 C)
{
  int   i,j,k;
  float ab;

  for(i=0; i<4; i++)
  {
    for(j=0; j<4; j++)
    {
      ab=0;
      for(k=0; k<4; k++)
	ab+=A[i][k]*B[k][j];
      C[i][j]=ab;
    }
  }
}

void MatCopy(Matx4x4 a, Matx4x4 b)
{
  Byte i, j;

  for(i=0; i<4; i++)
  {
    for(j=0; j<4; j++)
      b[i][j]=a[i][j];
  }
}

void PrepareMatrix(float Tx, float Ty, float Tz,
		   float Sx, float Sy, float Sz,
		   float Rx, float Ry, float Rz,
		   Matx4x4 XForm)
{
  Matx4x4 M1, M2, M3, M4, M5, M6, M7, M8, M9;

  Scale3D(Sx, Sy, Sz, M1);
  Rotate3D(1, Rx, M2);
  Rotate3D(2, Ry, M3);
  Rotate3D(3, Rz, M4);
  Translate3D(Tx, Ty, Tz, M5);
  Multiply3DMatricies(M2, M1, M6);
  Multiply3DMatricies(M3, M6, M7);
  Multiply3DMatricies(M4, M7, M8);
  Multiply3DMatricies(M5, M8, M9);
  MatCopy(M9, XForm);
}

void PrepareInvMatrix(float Tx, float Ty, float Tz,
		 float Sx, float Sy, float Sz,
		 float Rx, float Ry, float Rz,
		 Matx4x4 XForm)
{
  Matx4x4 M1, M2, M3, M4, M5, M6, M7, M8, M9;

  Scale3D(Sx, Sy, Sz, M1);
  Rotate3D(1, Rx, M2);
  Rotate3D(2, Ry, M3);
  Rotate3D(3, Rz, M4);
  Translate3D(Tx, Ty, Tz, M5);
  Multiply3DMatricies(M4, M5, M6);
  Multiply3DMatricies(M3, M6, M7);
  Multiply3DMatricies(M2, M7, M8);
  Multiply3DMatricies(M1, M8, M9);
  MatCopy(M9, XForm);
}

void Transform(TDA A, Matx4x4 M, TDA B)
{
  B[0]=M[0][0]*A[0]+M[0][1]*A[1]+M[0][2]*A[2]+M[0][3];
  B[1]=M[1][0]*A[0]+M[1][1]*A[1]+M[1][2]*A[2]+M[1][3];
  B[2]=M[2][0]*A[0]+M[2][1]*A[1]+M[2][2]*A[2]+M[2][3];
}



[ RETURN TO DIRECTORY ]