home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DOS/V Power Report 1997 March
/
VPR9703A.ISO
/
VPR_DATA
/
DOGA
/
SOURCES
/
REND.LZH
/
READER
/
MATRIX.C
< prev
next >
Wrap
C/C++ Source or Header
|
1995-11-07
|
6KB
|
364 lines
/*
行列演算関数群
Copyright T.Kobayashi
*/
#ifndef INLINE_MATRIX
#include <stdio.h>
#include <math.h>
#include <ctype.h>
#include <string.h>
#include "reader.h"
#define Static
#else
extern Float minscale;
#define Static static
#endif
#ifdef V70
#define RAD 0.0174532925199
#else
#define RAD (3.14159265358979/180.0)
#endif
/* ベクトルの表示 */
#if 1
Static inline void v_print( msg, v )
char *msg ;
Vector v ;
{
#if 0
fprintf( errfp, "%s\t%18g\t18g\t%18g\n", msg, v[0], v[1], v[2] ) ;
#endif
fprintf( errfp, "%s\t%18lf\t%18lf\t%18lf\n", msg, v[0], v[1], v[2] ) ;
}
/* 行列の表示 */
Static inline void m_print( m )
Matrix m ;
{
int i, j ;
for( i = 0 ; i < 4 ; ++i )
{
for( j = 0 ; j < 4 ; ++j )
fprintf( errfp, "%18g\t", m[i][j] );
putchar( '\n' ) ;
}
}
#endif
/* 行列の複写 */
Static inline void m_copy( a, b )
Matrix a, b ;
{
#if 0
int i, j ;
for( i = 0 ; i < 4 ; ++i )
for( j = 0 ; j < 4 ; ++j )
a[i][j] = b[i][j] ;
#endif
memcpy(a, b, sizeof(Matrix));
}
/*
* 行列
*/
#ifdef V70
static Matrix unit_matrix = {
1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0
} ;
#endif
/* 単位行列 */
Static inline void m_unit( a )
Matrix a ;
{
#ifndef V70
static Matrix m = {
{1.0, 0.0, 0.0, 0.0},
{0.0, 1.0, 0.0, 0.0},
{0.0, 0.0, 1.0, 0.0},
{0.0, 0.0, 0.0, 1.0}
} ;
m_copy( a, m );
#else
m_copy( a, unit_matrix );
#endif
}
/* 平行移動の行列生成 */
Static inline void m_mov( m, v )
Matrix m ;
Vector v ;
{
m_unit( m ) ;
v_copy( m[3], v ) ;
}
/*
回転の行列生成
type 0 : x軸回転
1 : y軸回転
2 : z軸回転
*/
Static inline void m_rot( Matrix m, int type, Float deg )
{
m_unit( m );
switch( type )
{
case 0 :
m[1][1] = cos( RAD * deg );
m[1][2] = sin( RAD * deg );
m[2][1] = - m[1][2] ;
m[2][2] = m[1][1] ;
break ;
case 1 :
m[2][2] = cos( RAD * deg );
m[2][0] = sin( RAD * deg );
m[0][2] = - m[2][0] ;
m[0][0] = m[2][2] ;
break ;
case 2 :
m[0][0] = cos( RAD * deg );
m[0][1] = sin( RAD * deg );
m[1][0] = - m[0][1] ;
m[1][1] = m[0][0] ;
break ;
}
}
/* スケールの行列生成 */
Static inline void m_scal( m, p )
Matrix m ;
Point p ;
{
m_unit( m );
m[0][0] = p[0] ;
m[1][1] = p[1] ;
m[2][2] = p[2] ;
}
/* ベクトル指定の行列生成 */
Static inline void m_vec( m, xv, zv )
Matrix m ;
Vector xv, zv ;
{
Vector yv ;
m_unit( m ) ;
v_pro( yv, zv, xv );
v_unit( xv, xv );
v_unit( yv, yv );
v_pro( zv, xv, yv );
v_copy( m[0], xv );
v_copy( m[1], yv );
v_copy( m[2], zv );
}
/* 行列の積 */
Static inline void m_mult( ret, a1, a2 )
Matrix ret, a1, a2 ;
{
int i, j, k ;
Float w ;
Matrix m ;
for ( i = 0 ; i < 4 ; ++i )
{
for ( j = 0 ; j < 4 ; ++j )
{
w = 0.0 ;
for ( k = 0 ; k < 4 ; ++k )
w += a1[i][k] * a2[k][j] ;
m[i][j] = w ;
}
}
m_copy( ret, m );
}
/* ベクトルと行列の積 */
Static inline void vec_mult_mat( ret, va, m, n, sw )
Vector *ret ;
Vector *va ;
Matrix m ;
int n, sw ;
{
int i, j;
Vector v ;
if ( sw ) {
for ( i = 0 ; i < n ; ++i )
{
for ( j = 0 ; j < 3 ; ++j )
{
v[j] = va[i][0]*m[0][j] + va[i][1]*m[1][j] + va[i][2]*m[2][j]
+ m[3][j];
}
v_copy( ret[i], v );
}
} else {
for ( i = 0 ; i < n ; ++i )
{
for ( j = 0 ; j < 3 ; ++j )
{
v[j] = va[i][0]*m[0][j] + va[i][1]*m[1][j] + va[i][2]*m[2][j];
}
v_copy( ret[i], v );
}
}
}
/* 転置行列 */
Static inline void m_trans( t, m )
Matrix t, m ;
{
int i, j ;
Matrix a ;
m_copy( a, m );
for( i = 0 ; i < 4 ; ++i )
{
for( j = 0 ; j < 4 ; ++j )
t[i][j] = a[j][i] ;
}
}
/*
逆行列
戻り値 0 : エラー
1 : 正常
*/
#if 0
static void m_g_mult( Matrix, Matrix, int, Float, int ) ;
static void m_g_div( Matrix, Matrix, int, Float ) ;
static void m_g_chg( Matrix, Matrix, int, int ) ;
#endif
static inline Float m_g_value(Vector v0, Vector v1, Vector v2)
{
return v0[0]*v1[1]*v2[2]+v1[0]*v2[1]*v0[2]+v2[0]*v0[1]*v1[2]
-v0[0]*v2[1]*v1[2]-v1[0]*v0[1]*v2[2]-v2[0]*v1[1]*v0[2];
}
Static inline int m_inv( inv, m )
Matrix inv, m ;
{
Float val;
m_unit( inv ) ;
val = m[0][0]*m[1][1]*m[2][2]+m[1][0]*m[2][1]*m[0][2]+m[2][0]*m[0][1]*m[1][2]
-m[0][0]*m[2][1]*m[1][2]-m[1][0]*m[0][1]*m[2][2]-m[2][0]*m[1][1]*m[0][2];
if (fabs(val) < 1e-10) {
return 0;
}
inv[0][0] = (m[1][1]*m[2][2]-m[2][1]*m[1][2])/val;
inv[0][1] = -(m[0][1]*m[2][2]-m[2][1]*m[0][2])/val;
inv[0][2] = (m[0][1]*m[1][2]-m[1][1]*m[0][2])/val;
inv[1][0] = -(m[1][0]*m[2][2]-m[2][0]*m[1][2])/val;
inv[1][1] = (m[0][0]*m[2][2]-m[2][0]*m[0][2])/val;
inv[1][2] = -(m[0][0]*m[1][2]-m[1][0]*m[0][2])/val;
inv[2][0] = (m[1][0]*m[2][1]-m[2][0]*m[1][1])/val;
inv[2][1] = -(m[0][0]*m[2][1]-m[2][0]*m[0][1])/val;
inv[2][2] = (m[0][0]*m[1][1]-m[1][0]*m[0][1])/val;
if (m[3][0] != 0.0 || m[3][1] != 0.0 || m[3][2] != 0.0) {
inv[3][0] = -m_g_value(m[1], m[2], m[3])/val;
inv[3][1] = m_g_value(m[0], m[2], m[3])/val;
inv[3][2] = -m_g_value(m[0], m[1], m[3])/val;
}
return 1;
}
#if 0
Static inline int m_inv( inv, m )
Matrix inv, m ;
{
int i, j ;
Matrix a ;
m_copy( a, m ) ;
m_unit( inv ) ;
for ( i = 0 ; i < 4 ; ++i )
{
if ( fabs( a[i][i] ) < 1e-10 )
{
for( j = i+1 ; j < 4 ; ++j )
{
if ( fabs( a[j][i] ) > minscale )
break ;
}
if ( j == 4 )
return( 0 ) ;
m_g_chg( a, inv, i, j );
}
m_g_div( a, inv, i, a[i][i] );
for( j = 0 ; j < 4 ; ++j )
{
if ( i == j )
continue ;
m_g_mult( a, inv, i, a[j][i], j ) ;
}
}
return( 1 );
}
static void m_g_mult( a1, a2, i, a, j )
Matrix a1, a2 ;
int i, j ;
Float a ;
{
int k ;
for( k = 0 ; k < 4 ; ++k )
{
a1[j][k] -= a1[i][k]*a ;
a2[j][k] -= a2[i][k]*a ;
}
}
static void m_g_div( a1, a2, i, a )
Matrix a1, a2 ;
int i ;
Float a ;
{
int k ;
for( k = 0 ; k < 4 ; ++k )
{
a1[i][k] /= a ;
a2[i][k] /= a ;
}
}
#define swap( a, b ) { Float w ; w = a ; a = b ; b = w ; }
static void m_g_chg( a1, a2, i, j )
Matrix a1, a2 ;
int i, j ;
{
int k ;
for( k = 0 ; k < 4 ; ++k )
{
swap( a1[i][k], a1[j][k] ) ;
swap( a2[i][k], a2[j][k] ) ;
}
}
#endif
#undef Static