示例#1
0
void matLookAt(float *a,float *aEye,float *aFocus,float *aUp)
{
    float m[16];
    float x[3],y[3],z[3];

    z[0]=aEye[0]-aFocus[0];
    z[1]=aEye[1]-aFocus[1];
    z[2]=aEye[2]-aFocus[2];

	matNormalize(z);
    
	y[0]=aUp[0];
    y[1]=aUp[1];
    y[2]=aUp[2];

	matCrossProduct(x,y,z);
	matNormalize(x);

	matCrossProduct(y,z,x);
	matNormalize(y);

#define M(row,col) m[(col<<2)+row]

    M(0,0)=x[0]; M(0,1)=x[1]; M(0,2)=x[2]; M(0,3)=0.0F;
    M(1,0)=y[0]; M(1,1)=y[1]; M(1,2)=y[2]; M(1,3)=0.0F;
    M(2,0)=z[0]; M(2,1)=z[1]; M(2,2)=z[2]; M(2,3)=0.0F;
    M(3,0)=0.0F; M(3,1)=0.0F; M(3,2)=0.0F; M(3,3)=1.0F;

#undef M

	matProduct(NULL,a,m);
	matTranslate(a,-aEye[0],-aEye[1],-aEye[2]);

	return;
}
示例#2
0
void matFrustum(float *a,float left,float right,float bottom,float top,float cnear,float cfar)
{
    float x,y,aa,bb,cc,dd;
    float m[16];

    x=(2.0F*cnear)/(right-left);
    y=(2.0F*cnear)/(top-bottom);
    aa=(right+left)/(right-left);
    bb=(top+bottom)/(top-bottom);
    cc=-(cfar+cnear)/(cfar-cnear);
    dd=-(2.0F*cfar*cnear)/(cfar-cnear);

#define M(row,ccol) m[(ccol<<2)+row]

    M(0,0)=x;    M(0,1)=0.0F; M(0,2)=aa;    M(0,3)=0.0F;
    M(1,0)=0.0F; M(1,1)=y;    M(1,2)=bb;    M(1,3)=0.0F;
    M(2,0)=0.0F; M(2,1)=0.0F; M(2,2)=cc;    M(2,3)=dd;
    M(3,0)=0.0F; M(3,1)=0.0F; M(3,2)=-1.0F; M(3,3)=0.0F;

#undef M

	matProduct(NULL,a,m);
}
void schurFactorization(long n, complex **A, complex **T, complex **U)
{

  /* Schur factorization: A = U*T*U', T = upper triangular, U = unitary */
            
  long i,j,iter,maxIter;
  double tol, diff1,diff2; 
  complex T11, T12, T21, T22; 
  complex sigma1, sigma2, sigma; 
  complex z, z1, z2; 
  complex **P, **Q, **R;


  /* Allocate auxiliary matrices */

  P     = (complex **)Mem(MEM_ALLOC,n, sizeof(complex *)); 
  Q     = (complex **)Mem(MEM_ALLOC,n, sizeof(complex *)); 
  R     = (complex **)Mem(MEM_ALLOC,n, sizeof(complex *)); 

  for (i=0; i<n; i++){
    P[i]     = (complex *)Mem(MEM_ALLOC,n, sizeof(complex)); 
    Q[i]     = (complex *)Mem(MEM_ALLOC,n, sizeof(complex)); 
    R[i]     = (complex *)Mem(MEM_ALLOC,n, sizeof(complex)); 
  }

  /* ------------------------------------------------------------*/

  /* Parameters for iteration */

   maxIter = 500;
   tol     = 1E-30; 

  /* ------------------------------------------------------------*/

  /* Init U = eye(n) (identity matrix) */

  for (i=0; i<n; i++){
    U[i][i].re = 1.0; 
    U[i][i].im = 0.0; 
  }  
  
  /* ------------------------------------------------------------*/

  /* Reduce A to Hessenberg form */

  hessFactorization(n,A,P,T); 

  /* ------------------------------------------------------------*/

  /* Compute Schur factorization of Hessenberg matrix T */


   for (j=n-1; j>0; j--){ /* Main loop */

     for (iter=0; iter<maxIter; iter++){ /* Iteration loop */

       sigma.re = T[j][j].re;
       sigma.im = T[j][j].im; 


       /* -- Use Wilkinson shift -- */

       /* submatrix considered in the shift */

       T11 = T[j-1][j-1];
       T12 = T[j-1][j];
       T21 = T[j][j-1];
       T22 = T[j][j];

       /* Compute eigenvalues of submatrix */

       z.re  = 0.0;
       z.im  = 0.0;
       z2.re = 0.0;
       z2.im = 0.0;

       /* z = T11*T11 + T22*T22 - 2*T11*T22 + 4*T12*T21 */

       z1 = c_mul(T11,T11);

       z  = c_add(z ,z1);
       z2 = c_add(z2,z1);
       
       z1 = c_mul(T22,T22);

       z  = c_add(z ,z1);
       z2 = c_add(z2,z1);

       z1 = c_mul(T11,T22);

       z1.re = -2.0 * z1.re;
       z1.im = -2.0 * z1.im;

       z  = c_add(z,z1);

       z1 = c_mul(T12,T21);
       z1.re = 4.0 * z1.re;
       z1.im = 4.0 * z1.im;
       z = c_add(z,z1);

       /* Square root*/

       z = c_sqrt(z);

       /* Eigenvalues */
       
       sigma1 = c_add(z2,z);
       sigma2 = c_sub(z2,z);

/*        printf("sigma1 = %e %e\n", sigma1.re, sigma1.im); */
/*        printf("sigma2 = %e %e\n", sigma2.re, sigma2.im); */

       /* Select eigenvalue for shift*/

       diff1 = c_norm( c_sub(T[j][j], sigma1) );
       diff2 = c_norm( c_sub(T[j][j], sigma2) );

       if (diff1 < diff2){
	 sigma.re = sigma1.re;
	 sigma.im = sigma1.im;
       }else{
	 sigma.re = sigma2.re;
	 sigma.im = sigma2.im;
       }

       /* --- QR step with Wilkinson shift --- */

       /* Shift: T(1:j,1:j) = T(1:j,1:j) - sigma * eye(j) */

       for (i=0; i<j+1; i++){

	 CheckValue(FUNCTION_NAME, "T[i][i].re","", T[i][i].re, -INFTY, INFTY);
	 CheckValue(FUNCTION_NAME, "T[i][i].im","", T[i][i].im, -INFTY, INFTY);	 

	 T[i][i].re = T[i][i].re - sigma.re;   
	 T[i][i].im = T[i][i].im - sigma.im;   
	 
       }

       /* Compute QR factorization of shifted Hessenberg matrix */

       for (i=0; i<n; i++){
	 memset(Q[i], 0, n*sizeof(complex));
	 memset(R[i], 0, n*sizeof(complex));
       }

       QRfactorization(n,T,Q,R); 

       /* T = T_new = R * Q  */

       for (i=0; i<n; i++){
	 memset(T[i], 0, n*sizeof(complex));
       }
       matProduct(n, n, n, R, Q, T);

       /* T(1:j,1:j) = T(1:j,1:j) + sigma * eye(j) */
       for (i=0; i<j+1; i++){
	 T[i][i].re = T[i][i].re + sigma.re;   
	 T[i][i].im = T[i][i].im + sigma.im;   
       }


       /* R =  U_new = U * Q */

       for (i=0; i<n; i++){
	 memset(R[i], 0, n*sizeof(complex));
       }       
       matProduct(n,n,n,U,Q,R); 

       /* U = R */

       for (i=0; i<n; i++){
	 memcpy(U[i],R[i], n*sizeof(complex));
       } 

       /* Check convergence */

       if (c_norm( T[j][j-1] ) <= tol * (c_norm(T[j-1][j-1]) + c_norm(T[j][j]))){
	 T[j][j-1].re = 0.0;
	 T[j][j-1].im = 0.0;
	 break; 
       }
       
   
     }	/* end of iter loop */  
    
   } /* end of main loop */


  /* -------------------------------------------------------------*/

   /* U = P*U */

   for (i=0; i<n; i++){
     memset(U[i], 0, n*sizeof(complex));
   }
   matProduct(n,n,n,P,R,U);
   

  /* -------------------------------------------------------------*/
  /* Free auxiliary variables */

   for (i=0; i<n; i++){
     Mem(MEM_FREE,P[i]); 
     Mem(MEM_FREE,Q[i]); 
     Mem(MEM_FREE,R[i]); 
   }

   Mem(MEM_FREE,P); 
   Mem(MEM_FREE,Q); 
   Mem(MEM_FREE,R); 

  /* Return */

  return;   
    
  
}
示例#4
0
void matRotate(float* a,float* axis,float angle)
{
    float mag,s,c;
    float xx,yy,zz,xy,yz,zx,xs,ys,zs,one_c;
    float x,y,z;
	float m[16];

    double rads;

	x=axis[0];
    y=axis[1];
    z=axis[2];

    rads=(double)angle*PI/180.0F;
    s=(float)sin(rads);
    c=(float)cos(rads);

    mag=(float)sqrt(x*x+y*y+z*z);
    if(mag == 0.0)
    {
	    matIdentity(m);
	    return;
    }

    x/=mag;
    y/=mag;
    z/=mag;

#define M(row,col) m[(col<<2)+row]

    xx=x*x;
    yy=y*y;
    zz=z*z;
    xy=x*y;
    yz=y*z;
    zx=z*x;
    xs=x*s;
    ys=y*s;
    zs=z*s;
    one_c=1.0F-c;

    M(0,0)=(one_c*xx)+c;
    M(0,1)=(one_c*xy)-zs;
    M(0,2)=(one_c*zx)+ys;
    M(0,3)=0.0F;

    M(1,0)=(one_c*xy)+zs;
    M(1,1)=(one_c*yy)+c;
    M(1,2)=(one_c*yz)-xs;
    M(1,3)=0.0F;

    M(2,0)=(one_c*zx)-ys;
    M(2,1)=(one_c*yz)+xs;
    M(2,2)=(one_c*zz)+c;
    M(2,3)=0.0F;

    M(3,0)=0.0F;
    M(3,1)=0.0F;
    M(3,2)=0.0F;
    M(3,3)=1.0F;

#undef M

	matProduct(NULL,a,m);
	
	return;
}