⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fmatmul.c

📁 Graphics Gems 源码 a collection of algorithms, programs, and mathematical techniques for the computer
💻 C
字号:
/*  FILENAME: FastMatMul.c  [revised 18 AUG 90]    AUTHOR:  Kelvin Thompson    DESCRIPTION:  Routines to multiply different kinds of 4x4      matrices as fast as possible.  Based on ideas on pages 454,      460-461, and 646 of _Graphics_Gems_.	These routines offer two advantages over the standard      V3MatMul in the _Graphics_Gems_ vector library GGVecLib.c.      First, the routines are faster.  Second, they can handle      input matrices that are the same as the output matrix.      The routines have the disadvantage of taking more code      space (from unwound loops).        The routines are about as fast as you can get for      general-purpose multiplication.  If you have special      knowledge about your system, you may be able to improve      them a little more:        [1]  If you know that your input and output matrices will      never overlap: remove the tests near the beginning and end of      each routine, and just #define 'mptr' to 'result'.  (The      standard library's V3MatMul makes this assumption.)	[2]  If you know that your compiler supports more than      three pointer-to-double registers in a subroutine: make      'result' in each routine a register variable.  You might      also make the 'usetemp' boolean a register.	[3]  If you have limited stack space, or your system can      access global memory faster than stack:  make each routine's      'tempx' a static, or let all routines share a global 'tempx'.      (This is useless if assumption [1] holds.)*//* definitions from "GGems.h" */typedef struct Matrix3Struct {	/* 3-by-3 matrix */	double element[3][3];	} Matrix3;typedef struct Matrix4Struct {	/* 4-by-4 matrix */	double element[4][4];	} Matrix4;/* routines in this file */Matrix3 *V2MatMul();     /* general 3x3 matrix multiplier */Matrix4 *V3MatMul();     /* general 4x4 matrix multiplier */Matrix4 *V3AffMatMul();  /* affine 4x4 matrix multiplier */Matrix4 *V3LinMatMul();  /* linear 4x4 matrix multiplier *//* macro to access matrix element */#define MVAL(mptr,row,col)  ((mptr)->element[row][col])/*  ************************************    *                                  *    *           V2MatMul               *    *                                  *    ************************************    DESCRIPTION:  Multiply two general 3x3 matrices.  If one of      the input matrices is the same as the output, write the      result to a temporary matrix during multiplication, then      copy to the output matrix.    ENTRY:      a -- pointer to left matrix      b -- pointer to right matrix      result -- result matrix    EXIT:  returns 'result'*/Matrix3 *V2MatMul ( a, b, result )register Matrix3 *a,*b;Matrix3 *result;{register Matrix3 *mptr;int usetemp;  /* boolean */Matrix3 tempx;/* decide where intermediate result goes */usetemp = ( a == result  ||  b == result );if ( usetemp )  mptr = & tempx;else  mptr = result;MVAL(mptr,0,0) =     MVAL(a,0,0) * MVAL(b,0,0)  +  MVAL(a,0,1) * MVAL(b,1,0)  +  MVAL(a,0,2) * MVAL(b,2,0);MVAL(mptr,0,1) =     MVAL(a,0,0) * MVAL(b,0,1)  +  MVAL(a,0,1) * MVAL(b,1,1)  +  MVAL(a,0,2) * MVAL(b,2,1);MVAL(mptr,0,2) =     MVAL(a,0,0) * MVAL(b,0,2)  +  MVAL(a,0,1) * MVAL(b,1,2)  +  MVAL(a,0,2) * MVAL(b,2,2);MVAL(mptr,1,0) =     MVAL(a,1,0) * MVAL(b,0,0)  +  MVAL(a,1,1) * MVAL(b,1,0)  +  MVAL(a,1,2) * MVAL(b,2,0);MVAL(mptr,1,1) =     MVAL(a,1,0) * MVAL(b,0,1)  +  MVAL(a,1,1) * MVAL(b,1,1)  +  MVAL(a,1,2) * MVAL(b,2,1);MVAL(mptr,1,2) =     MVAL(a,1,0) * MVAL(b,0,2)  +  MVAL(a,1,1) * MVAL(b,1,2)  +  MVAL(a,1,2) * MVAL(b,2,2);MVAL(mptr,2,0) =     MVAL(a,2,0) * MVAL(b,0,0)  +  MVAL(a,2,1) * MVAL(b,1,0)  +  MVAL(a,2,2) * MVAL(b,2,0);MVAL(mptr,2,1) =     MVAL(a,2,0) * MVAL(b,0,1)  +  MVAL(a,2,1) * MVAL(b,1,1)  +  MVAL(a,2,2) * MVAL(b,2,1);MVAL(mptr,2,2) =     MVAL(a,2,0) * MVAL(b,0,2)  +  MVAL(a,2,1) * MVAL(b,1,2)  +  MVAL(a,2,2) * MVAL(b,2,2);/* copy temp matrix to result if needed */if ( usetemp )  *result = *mptr;return result;}/*  ************************************    *                                  *    *           V3MatMul               *    *                                  *    ************************************    DESCRIPTION:  Multiply two general 4x4 matrices.  If one of      the input matrices is the same as the output, write the      result to a temporary matrix during multiplication, then      copy to the output matrix.    ENTRY:      a -- pointer to left matrix      b -- pointer to right matrix      result -- result matrix    EXIT:  returns 'result'*/Matrix4 *V3MatMul ( a, b, result )register Matrix4 *a,*b;Matrix4 *result;{register Matrix4 *mptr;int usetemp;  /* boolean */Matrix4 tempx;/* decide where intermediate result goes */usetemp = ( a == result  ||  b == result );if ( usetemp )  mptr = & tempx;else  mptr = result;MVAL(mptr,0,0) =     MVAL(a,0,0) * MVAL(b,0,0)  +  MVAL(a,0,1) * MVAL(b,1,0)  +  MVAL(a,0,2) * MVAL(b,2,0)  +  MVAL(a,0,3) * MVAL(b,3,0);MVAL(mptr,0,1) =     MVAL(a,0,0) * MVAL(b,0,1)  +  MVAL(a,0,1) * MVAL(b,1,1)  +  MVAL(a,0,2) * MVAL(b,2,1)  +  MVAL(a,0,3) * MVAL(b,3,1);MVAL(mptr,0,2) =     MVAL(a,0,0) * MVAL(b,0,2)  +  MVAL(a,0,1) * MVAL(b,1,2)  +  MVAL(a,0,2) * MVAL(b,2,2)  +  MVAL(a,0,3) * MVAL(b,3,2);MVAL(mptr,0,3) =     MVAL(a,0,0) * MVAL(b,0,3)  +  MVAL(a,0,1) * MVAL(b,1,3)  +  MVAL(a,0,2) * MVAL(b,2,3)  +  MVAL(a,0,3) * MVAL(b,3,3);MVAL(mptr,1,0) =     MVAL(a,1,0) * MVAL(b,0,0)  +  MVAL(a,1,1) * MVAL(b,1,0)  +  MVAL(a,1,2) * MVAL(b,2,0)  +  MVAL(a,1,3) * MVAL(b,3,0);MVAL(mptr,1,1) =     MVAL(a,1,0) * MVAL(b,0,1)  +  MVAL(a,1,1) * MVAL(b,1,1)  +  MVAL(a,1,2) * MVAL(b,2,1)  +  MVAL(a,1,3) * MVAL(b,3,1);MVAL(mptr,1,2) =     MVAL(a,1,0) * MVAL(b,0,2)  +  MVAL(a,1,1) * MVAL(b,1,2)  +  MVAL(a,1,2) * MVAL(b,2,2)  +  MVAL(a,1,3) * MVAL(b,3,2);MVAL(mptr,1,3) =     MVAL(a,1,0) * MVAL(b,0,3)  +  MVAL(a,1,1) * MVAL(b,1,3)  +  MVAL(a,1,2) * MVAL(b,2,3)  +  MVAL(a,1,3) * MVAL(b,3,3);MVAL(mptr,2,0) =     MVAL(a,2,0) * MVAL(b,0,0)  +  MVAL(a,2,1) * MVAL(b,1,0)  +  MVAL(a,2,2) * MVAL(b,2,0)  +  MVAL(a,2,3) * MVAL(b,3,0);MVAL(mptr,2,1) =     MVAL(a,2,0) * MVAL(b,0,1)  +  MVAL(a,2,1) * MVAL(b,1,1)  +  MVAL(a,2,2) * MVAL(b,2,1)  +  MVAL(a,2,3) * MVAL(b,3,1);MVAL(mptr,2,2) =     MVAL(a,2,0) * MVAL(b,0,2)  +  MVAL(a,2,1) * MVAL(b,1,2)  +  MVAL(a,2,2) * MVAL(b,2,2)  +  MVAL(a,2,3) * MVAL(b,3,2);MVAL(mptr,2,3) =     MVAL(a,2,0) * MVAL(b,0,3)  +  MVAL(a,2,1) * MVAL(b,1,3)  +  MVAL(a,2,2) * MVAL(b,2,3)  +  MVAL(a,2,3) * MVAL(b,3,3);MVAL(mptr,3,0) =     MVAL(a,3,0) * MVAL(b,0,0)  +  MVAL(a,3,1) * MVAL(b,1,0)  +  MVAL(a,3,2) * MVAL(b,2,0)  +  MVAL(a,3,3) * MVAL(b,3,0);MVAL(mptr,3,1) =     MVAL(a,3,0) * MVAL(b,0,1)  +  MVAL(a,3,1) * MVAL(b,1,1)  +  MVAL(a,3,2) * MVAL(b,2,1)  +  MVAL(a,3,3) * MVAL(b,3,1);MVAL(mptr,3,2) =     MVAL(a,3,0) * MVAL(b,0,2)  +  MVAL(a,3,1) * MVAL(b,1,2)  +  MVAL(a,3,2) * MVAL(b,2,2)  +  MVAL(a,3,3) * MVAL(b,3,2);MVAL(mptr,3,3) =     MVAL(a,3,0) * MVAL(b,0,3)  +  MVAL(a,3,1) * MVAL(b,1,3)  +  MVAL(a,3,2) * MVAL(b,2,3)  +  MVAL(a,3,3) * MVAL(b,3,3);/* copy temp matrix to result if needed */if ( usetemp )  *result = *mptr;return result;}/*  ************************************    *                                  *    *        V3AffMatMul               *    *                                  *    ************************************    DESCRIPTION:  Multiply two affine 4x4 matrices.  The      routine assumes the rightmost column of each input      matrix is [0 0 0 1].  The output matrix will have the      same property.          If one of the input matrices is the same as the output,      write the result to a temporary matrix during multiplication,      then copy to the output matrix.    ENTRY:      a -- pointer to left matrix      b -- pointer to right matrix      result -- result matrix    EXIT:  returns 'result'*/Matrix4 *V3AffMatMul ( a, b, result )register Matrix4 *a,*b;Matrix4 *result;{register Matrix4 *mptr;int usetemp;  /* boolean */Matrix4 tempx;/* decide where intermediate result goes */usetemp = ( a == result  ||  b == result );if ( usetemp )  mptr = & tempx;else  mptr = result;MVAL(mptr,0,0) =     MVAL(a,0,0) * MVAL(b,0,0)  +  MVAL(a,0,1) * MVAL(b,1,0)  +  MVAL(a,0,2) * MVAL(b,2,0);MVAL(mptr,0,1) =     MVAL(a,0,0) * MVAL(b,0,1)  +  MVAL(a,0,1) * MVAL(b,1,1)  +  MVAL(a,0,2) * MVAL(b,2,1);MVAL(mptr,0,2) =     MVAL(a,0,0) * MVAL(b,0,2)  +  MVAL(a,0,1) * MVAL(b,1,2)  +  MVAL(a,0,2) * MVAL(b,2,2);MVAL(mptr,0,3) = 0.0;MVAL(mptr,1,0) =     MVAL(a,1,0) * MVAL(b,0,0)  +  MVAL(a,1,1) * MVAL(b,1,0)  +  MVAL(a,1,2) * MVAL(b,2,0);MVAL(mptr,1,1) =     MVAL(a,1,0) * MVAL(b,0,1)  +  MVAL(a,1,1) * MVAL(b,1,1)  +  MVAL(a,1,2) * MVAL(b,2,1);MVAL(mptr,1,2) =     MVAL(a,1,0) * MVAL(b,0,2)  +  MVAL(a,1,1) * MVAL(b,1,2)  +  MVAL(a,1,2) * MVAL(b,2,2);MVAL(mptr,1,3) = 0.0;MVAL(mptr,2,0) =     MVAL(a,2,0) * MVAL(b,0,0)  +  MVAL(a,2,1) * MVAL(b,1,0)  +  MVAL(a,2,2) * MVAL(b,2,0);MVAL(mptr,2,1) =     MVAL(a,2,0) * MVAL(b,0,1)  +  MVAL(a,2,1) * MVAL(b,1,1)  +  MVAL(a,2,2) * MVAL(b,2,1);MVAL(mptr,2,2) =     MVAL(a,2,0) * MVAL(b,0,2)  +  MVAL(a,2,1) * MVAL(b,1,2)  +  MVAL(a,2,2) * MVAL(b,2,2);MVAL(mptr,2,3) = 0.0;MVAL(mptr,3,0) =     MVAL(a,3,0) * MVAL(b,0,0)  +  MVAL(a,3,1) * MVAL(b,1,0)  +  MVAL(a,3,2) * MVAL(b,2,0)  +                MVAL(b,3,0);MVAL(mptr,3,1) =     MVAL(a,3,0) * MVAL(b,0,1)  +  MVAL(a,3,1) * MVAL(b,1,1)  +  MVAL(a,3,2) * MVAL(b,2,1)  +                MVAL(b,3,1);MVAL(mptr,3,2) =     MVAL(a,3,0) * MVAL(b,0,2)  +  MVAL(a,3,1) * MVAL(b,1,2)  +  MVAL(a,3,2) * MVAL(b,2,2)  +                MVAL(b,3,2);MVAL(mptr,3,3) = 1.0;/* copy temp matrix to result if needed */if ( usetemp )  *result = *mptr;return result;}/*  ************************************    *                                  *    *        V3LinMatMul               *    *                                  *    ************************************    DESCRIPTION:  Multiply two affine 4x4 matrices.  The      routine assumes the right column and bottom line      of each input matrix is [0 0 0 1].  The output matrix      will have the same property.  This is pretty much the      same thing as multiplying two 3x3 matrices.          If one of the input matrices is the same as the output,      write the result to a temporary matrix during multiplication,      then copy to the output matrix.    ENTRY:      a -- pointer to left matrix      b -- pointer to right matrix      result -- result matrix    EXIT:  returns 'result'*/Matrix4 *V3LinMatMul ( a, b, result )register Matrix4 *a,*b;Matrix4 *result;{register Matrix4 *mptr;int usetemp;  /* boolean */Matrix4 tempx;/* decide where intermediate result goes */usetemp = ( a == result  ||  b == result );if ( usetemp )  mptr = & tempx;else  mptr = result;MVAL(mptr,0,0) =     MVAL(a,0,0) * MVAL(b,0,0)  +  MVAL(a,0,1) * MVAL(b,1,0)  +  MVAL(a,0,2) * MVAL(b,2,0);MVAL(mptr,0,1) =     MVAL(a,0,0) * MVAL(b,0,1)  +  MVAL(a,0,1) * MVAL(b,1,1)  +  MVAL(a,0,2) * MVAL(b,2,1);MVAL(mptr,0,2) =     MVAL(a,0,0) * MVAL(b,0,2)  +  MVAL(a,0,1) * MVAL(b,1,2)  +  MVAL(a,0,2) * MVAL(b,2,2);MVAL(mptr,0,3) = 0.0;MVAL(mptr,1,0) =     MVAL(a,1,0) * MVAL(b,0,0)  +  MVAL(a,1,1) * MVAL(b,1,0)  +  MVAL(a,1,2) * MVAL(b,2,0);MVAL(mptr,1,1) =     MVAL(a,1,0) * MVAL(b,0,1)  +  MVAL(a,1,1) * MVAL(b,1,1)  +  MVAL(a,1,2) * MVAL(b,2,1);MVAL(mptr,1,2) =     MVAL(a,1,0) * MVAL(b,0,2)  +  MVAL(a,1,1) * MVAL(b,1,2)  +  MVAL(a,1,2) * MVAL(b,2,2);MVAL(mptr,1,3) = 0.0;MVAL(mptr,2,0) =     MVAL(a,2,0) * MVAL(b,0,0)  +  MVAL(a,2,1) * MVAL(b,1,0)  +  MVAL(a,2,2) * MVAL(b,2,0);MVAL(mptr,2,1) =     MVAL(a,2,0) * MVAL(b,0,1)  +  MVAL(a,2,1) * MVAL(b,1,1)  +  MVAL(a,2,2) * MVAL(b,2,1);MVAL(mptr,2,2) =     MVAL(a,2,0) * MVAL(b,0,2)  +  MVAL(a,2,1) * MVAL(b,1,2)  +  MVAL(a,2,2) * MVAL(b,2,2);MVAL(mptr,2,3) = 0.0;MVAL(mptr,3,0) = 0.0;MVAL(mptr,3,1) = 0.0;MVAL(mptr,3,2) = 0.0;MVAL(mptr,3,3) = 1.0;/* copy temp matrix to result if needed */if ( usetemp )  *result = *mptr;return result;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -