示例#1
0
void Matrix3by3Inverse( double** M, double** M_inv ) {
	double determinant	= 0;		/* Variable for the matrix determinant of M */
	double C_ji;					/* Co-factor C_ji of element M_ji, related to M_inv by:  M_inv_ij = C_ji/det(M) */
	double det_inv;					/* Variable for the inverse of the determinant */
	double epsilon		= 0.0001;	/* Acceptable tolerance for concluding that a determinant equals 0 (and hence that M is non-invertible) */

	/* Compute the determinant */
	for ( int i = 0; i < 3; i++ ) {
		determinant = determinant + M[0][i] * ( M[1][(i+1)%3] * M[2][(i+2)%3] - M[1][(i+2)%3] * M[2][(i+1)%3] );
	}
	
	/* If the determinant is too small, abort */
	assert( determinant > epsilon );
	det_inv = 1.0 / determinant;

	/* Find the inverse of the matrix */
	for ( int i = 0; i < 3; i++ ) {
		for ( int j = 0; j < 3; j++ ) {
			C_ji		= ( M[(j+1)%3][(i+1)%3] * M[(j+2)%3][(i+2)%3] ) - ( M[(j+1)%3][(i+2)%3] * M[(j+2)%3][(i+1)%3] );
			M_inv[i][j] = C_ji * det_inv;
		}
	}

	/* Check that the identity matrix results for M*M^-1 */
	double** Product = Make2DDoubleArray(3,3);
	MatrixMultiply(M,M_inv,3,3,3,Product);
	for ( int i = 0; i < 3; i++ ) {
		for ( int j = 0; j < 3; j++ ) {
			if (i == j) assert( fabs(Product[i][j] - 1) < epsilon );
			else assert( fabs(Product[i][j]) < epsilon );
		}
	}
	free(Product);
}
示例#2
0
int main(){
    int i,j,rozmiara,rozmiarb;
    char a;
    printf("Podaj rozmiar tablicy xn: \n");
    scanf("%d",&rozmiara);
    printf("Podaj rozmiar tablicy yn: \n");
    scanf("%d",&rozmiarb);
    double** myArray = Make2DDoubleArray(rozmiara, rozmiarb);
    
     for ( i = 0; i < rozmiara; i++ )
   {
      for ( j = 0; j < rozmiarb; j++ )
      {
         printf("a[%d][%d] podaj wartosc\n", i,j);
         scanf("%f",&myArray[i][j]);
      }
   }
    printf("Podaj rozmiar tablicy yn: %d\n",sizeof(myArray));
    scanf("%d",&rozmiarb);
  
    
    return 0;
    }
示例#3
0
void FindRotMat( double* v, double* v_out, double** R ) {
	
	double a[3], a_prime[3], b[3], b_prime[3], c[3], c_norm;	/* a = v_hat, a' = v_out_hat, c = c' is perp to both, and b, b' each complete the RHR */
	double** R1			= Make2DDoubleArray(3,3);				/* The matrix R1 rotates from the reference frame to a frame x-aligned with v */
	double** R1_inv		= Make2DDoubleArray(3,3);				/* Inverse of R1 */
	double** R3			= Make2DDoubleArray(3,3);				/* The matrix R3 rotates from the reference frame to a frame x-aligned with v_out */
	double v_norm		= Norm(v,3,2.0);						/* Magnitude of v */
	double v_out_norm	= Norm(v_out,3,2.0);					/* Magnitude of v_out */
	double epsilon		= 0.0001;								/* Tolerance for testing non-zero values of v and v_out (for testing degenerate cases) */

	/* Make sure v and v_out are non-zero vectors */
	assert( fabs(v[0]) > epsilon || fabs(v[1]) > epsilon || fabs(v[2]) > epsilon );
	assert( fabs(v_out[0]) > epsilon || fabs(v_out[1]) > epsilon || fabs(v_out[2]) > epsilon );
	
	/* Check if v and v_out are parallel.  If so, output the identity matrix.  If not, continue. */
	if ( fabs( (v[0]*v_out[0] + v[1]*v_out[1] + v[2]*v_out[2])/(v_norm*v_out_norm) - 1 ) < epsilon ) {
		IdentityMatrix( R, 3 );
	}
	else {

		/* Define a and a' */
		for (int i = 0; i < 3; i++) {
			a[i]		= v[i]/v_norm;
			a_prime[i]	= v_out[i]/v_out_norm;
		}
		
		/* Define c and c' (c' = c).  If v and v_out are anti-parallel, use SVD instead of the cross product to find an orthogonal vector. */
		if ( fabs( a[0]*a_prime[0] + a[1]*a_prime[1] + a[2]*a_prime[2] + 1 ) < epsilon ) {
			if (fabs(a[0]) > epsilon) {
				c[2] = pow( 1.0/ (1.0 + (a[2]/a[0])), 0.5 );
				c[0] = -(a[2]/a[0])*c[2];
				c[1] = 0;
			}
			else if (fabs(a[1]) > epsilon) {
				c[0] = 0;
				c[2] = pow( 1.0/ (1.0 + (a[2]/a[1])), 0.5 );
				c[1] = -(a[2]/a[1])*c[2];
			}
			else {
				c[0] = 0;
				c[1] = pow( 1.0/ (1.0 + (a[1]/a[2])), 0.5 );
				c[2] = -(a[1]/a[2])*c[1];
			}
		}
		else {
			Cross(a,a_prime,c);
			c_norm = Norm(c,3,2.0);
			for (int i = 0; i < 3; i++) {
				c[i] = c[i]/c_norm;
			}
		}

		/* Define b and b' (no normalization needed since c _|_ a and c' _|_ a' by definition) */
		Cross(c,a,b);
		Cross(c,a_prime,b_prime);

		/* Define R1 = [a, b, c] and R3 = [a', b', c'] */
		for (int i = 0; i < 3; i++) {
			R1[i][0] = a[i];
			R1[i][1] = b[i];
			R1[i][2] = c[i];
			R3[i][0] = a_prime[i];
			R3[i][1] = b_prime[i];
			R3[i][2] = c[i];
		}

		/* Now, R = R3*R1^-1 */
		Matrix3by3Inverse(R1, R1_inv);
		MatrixMultiply(R3, R1_inv, 3, 3, 3, R);
	}

	for (int i = 2; i >= 0; i--) {
		free(R1[i]); free(R1_inv[i]); free(R3[i]);
	}
	free(R1); free(R1_inv); free(R3);
}