sparse.c

来自「[Game.Programming].Academic - Graphics G」· C语言 代码 · 共 214 行

C
214
字号
/* *  Author: Jim Arvo * *  Corrected 11/05/91 to remove a redundant form.  The "C1" form as it *  appeared in GemsII was unnecessary. */#include "GraphicsGems.h"#define P1 (1<< 0)#define P2 (1<< 1)#define P3 (1<< 2)#define P4 (1<< 3)#define P5 (1<< 4)  #define P6 (1<< 5)#define RX (1<< 6)#define RY (1<< 7)#define RZ (1<< 8)#define C1 (1<< 9)#define C2 (1<<10)#define C3 (1<<11)#define C4 (1<<12)#define C5 (1<<13)#define C6 (1<<14)/*-------------------------------------------------------------------------*  *                                                                         * * This function classifies a 3x3 matrix according to its zero structure.  *  * It returns an unsigned integer in which each bit signifies a zero       * * structure that describes the given matrix.  If all bits are zero it     * * means the matrix is dense or does not fit any of these 15 forms.        * *                                                                         * *                                                                         * *  Permutations:                                                          * *                                                                         * *  * 0 0     0 * 0     0 0 *     0 * 0     * 0 0      0 0 *               * *  0 * 0     0 0 *     * 0 0     * 0 0     0 0 *      0 * 0               * *  0 0 *     * 0 0     0 * 0     0 0 *     0 * 0      * 0 0               * *                                                                         * *   P1        P2        P3        P4        P5         P6                 * *                                                                         * *                                                                         * *  Simple Rotations:                                                      * *                                                                         * *  * 0 0     * 0 *     * * 0                                              * *  0 * *     0 * 0     * * 0                                              * *  0 * *     * 0 *     0 0 *                                              * *                                                                         * *   RX        RY        RZ                                                * *                                                                         * *                                                                         * *  Permutations of the simple rotations:                                  * *                                                                         * *  0 0 *     0 * *     0 * 0     * * 0     * 0 *     0 * *                * *  * * 0     0 * *     * 0 *     0 0 *     * 0 *     * 0 0                * *  * * 0     * 0 0     * 0 *     * * 0     0 * 0     0 * *                * *                                                                         * *   C1        C2        C3        C4        C5        C6                  * *                                                                         * *-------------------------------------------------------------------------*/unsigned int classify_matrix( M )Matrix3  M;    {    unsigned int form = 0xFFFF;    /* Classify based on the diagonal elements. */    if( M.element[0][0] != 0 ) form &= P1 | P5 | RX | RY | RZ | C4 | C5;    if( M.element[1][1] != 0 ) form &= P1 | P6 | RX | RY | RZ | C1 | C2;    if( M.element[2][2] != 0 ) form &= P1 | P4 | RX | RY | RZ | C3 | C6;    /* Classify based on the upper triangular elements. */    if( M.element[0][1] != 0 ) form &= P2 | P4 | RZ | C2 | C3 | C4 | C6;    if( M.element[0][2] != 0 ) form &= P3 | P6 | RY | C1 | C2 | C5 | C6;    if( M.element[1][2] != 0 ) form &= P2 | P5 | RX | C2 | C3 | C4 | C5;    /* Classify based on the lower triangular elements. */    if( M.element[1][0] != 0 ) form &= P3 | P4 | RZ | C1 | C3 | C5 | C6;    if( M.element[2][0] != 0 ) form &= P2 | P6 | RY | C1 | C2 | C3 | C4;    if( M.element[2][1] != 0 ) form &= P3 | P5 | RX | C1 | C4 | C5 | C6;    /* If multiple classifications apply, return only one.  Doing this */    /* makes it possible to do a "switch" on the returned value.       */    if( form & P1 ) return( P1 );    if( form & P2 ) return( P2 );    if( form & P3 ) return( P3 );    if( form & P4 ) return( P4 );    if( form & P5 ) return( P5 );    if( form & P6 ) return( P6 );    if( form & RX ) return( RX );    if( form & RY ) return( RY );    if( form & RZ ) return( RZ );    if( form & C1 ) return( C1 );    if( form & C2 ) return( C2 );    if( form & C3 ) return( C3 );    if( form & C4 ) return( C4 );    if( form & C5 ) return( C5 );    if( form & C6 ) return( C6 );    return( form );    }/*-------------------------------------------------------------------------*  *                                                                         * * This routine transforms a vector "v" by a matrix "M" whose structure    * * is specified by "form".  The result is returned in the vector "w".      * * Note that "v" and "w" cannot be the same vector.                        * *                                                                         * * All zero elements must still be stored in the matrix "M"; the form      * * argument simply indicates which ones to use.  Thus, no storage is       * * saved in this implementation -- just time.                              * *                                                                         * *-------------------------------------------------------------------------*/void sparse_transform( M, form, v, w )Matrix3 M;unsigned int form;Vector3 *v;Vector3 *w;    {    switch( form )        {        case P1:            w->x = M.element[0][0] * v->x;            w->y = M.element[1][1] * v->y;            w->z = M.element[2][2] * v->z;            break;        case P2:            w->x = M.element[0][1] * v->x;            w->y = M.element[1][2] * v->y;            w->z = M.element[2][0] * v->z;            break;        case P3:            w->x = M.element[0][2] * v->x;            w->y = M.element[1][0] * v->y;            w->z = M.element[2][1] * v->z;            break;        case P4:            w->x = M.element[0][1] * v->x;            w->y = M.element[1][0] * v->y;            w->z = M.element[2][2] * v->z;            break;        case P5:            w->x = M.element[0][0] * v->x;            w->y = M.element[1][2] * v->y;            w->z = M.element[2][1] * v->z;            break;        case P6:            w->x = M.element[0][2] * v->x;            w->y = M.element[1][1] * v->y;            w->z = M.element[2][0] * v->z;            break;        case RX:            w->x = M.element[0][0] * v->x;            w->y = M.element[1][1] * v->y + M.element[1][2] * v->z;            w->z = M.element[2][1] * v->y + M.element[2][2] * v->z;            break;        case RY:             w->x = M.element[0][0] * v->x + M.element[0][2] * v->z;            w->y = M.element[1][1] * v->y;            w->z = M.element[2][0] * v->x + M.element[2][2] * v->z;            break;        case RZ:             w->x = M.element[0][0] * v->x + M.element[0][1] * v->y;            w->y = M.element[1][0] * v->x + M.element[1][1] * v->y;            w->z = M.element[2][2] * v->z;            break;        case C1:             w->x = M.element[0][2] * v->z;            w->y = M.element[1][0] * v->x + M.element[1][1] * v->y;            w->z = M.element[2][0] * v->x + M.element[2][1] * v->y;            break;        case C2:             w->x = M.element[0][1] * v->y + M.element[0][2] * v->z;            w->y = M.element[1][1] * v->y + M.element[1][2] * v->z;            w->z = M.element[2][0] * v->x;            break;        case C3:             w->x = M.element[0][1] * v->y;            w->y = M.element[1][0] * v->x + M.element[1][2] * v->z;            w->z = M.element[2][0] * v->x + M.element[2][2] * v->z;            break;        case C4:             w->x = M.element[0][0] * v->x + M.element[0][1] * v->y;            w->y = M.element[1][2] * v->z;            w->z = M.element[2][0] * v->x + M.element[2][1] * v->y;            break;        case C5:             w->x = M.element[0][0] * v->x + M.element[0][2] * v->z;            w->y = M.element[1][0] * v->x + M.element[1][2] * v->z;            w->z = M.element[2][1] * v->y;            break;        case C6:             w->x = M.element[0][1] * v->y + M.element[0][2] * v->z;            w->y = M.element[1][0] * v->x;            w->z = M.element[2][1] * v->y + M.element[2][2] * v->z;            break;        default:             w->x = M.element[0][0] * v->x + M.element[0][1] * v->y + M.element[0][2] * v->z;            w->y = M.element[1][0] * v->x + M.element[1][1] * v->y + M.element[1][2] * v->z;            w->z = M.element[2][0] * v->x + M.element[2][1] * v->y + M.element[2][2] * v->z;            break;        } /* switch */    } /* sparse_transform */

⌨️ 快捷键说明

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