Ejemplo n.º 1
0
// Helper routine for SVD conversion from bidiagonal to diagonal
bool MatrixRmn::UpdateBidiagIndices( long *firstBidiagIdx, long *lastBidiagIdx, VectorRn& w, VectorRn& superDiag, double eps )
{
	long lastIdx = *lastBidiagIdx;
	double* sdPtr = superDiag.GetPtr( lastIdx-1 );		// Entry above the last diagonal entry
	while ( NearZero(*sdPtr, eps) ) {				
		*(sdPtr--) = 0.0;
		lastIdx--;
		if ( lastIdx == 0 ) {
			return false;
		}
	}
	*lastBidiagIdx = lastIdx;
	long firstIdx = lastIdx-1;
	double* wPtr = w.GetPtr( firstIdx );
	while ( firstIdx > 0 ) {
		if ( NearZero( *wPtr, eps ) ) {			// If this diagonal entry (near) zero
			*wPtr = 0.0;
			break;
		}
		if ( NearZero(*(--sdPtr), eps) ) {		// If the entry above the diagonal entry is (near) zero
			*sdPtr = 0.0;
			break;
		}
		wPtr--;
		firstIdx--;
	}
	*firstBidiagIdx = firstIdx;
	return true;
}
Ejemplo n.º 2
0
float4 float4::normalize() const
{
	f32 lsqr = LengthSquared();
	if(NearZero(lsqr)) { return ZERO; };
	f32 recip = InvSqrt(lsqr);
	
	return float4(vec[0]*recip, vec[1]*recip, vec[2]*recip, vec[3]*recip);
};
Ejemplo n.º 3
0
// This is called when there is a zero diagonal entry, with a non-zero superdiagonal entry in the same column.
// We use Givens rotations to "chase" the non-zero entry up the column; when it reaches the last
//	column, it is finally zeroed away.
// wPtr points to the zero entry on the diagonal.  sdPtr points to the non-zero superdiagonal entry in the same column.
void MatrixRmn::ClearColumnWithDiagonalZero( long endIdx, MatrixRmn& V, double *wPtr, double *sdPtr, double eps )
{
	double curSd = *sdPtr;		// Value being chased up the column
	*sdPtr = 0.0;
	long i = endIdx-1;
	while ( true ) {
		double c, s;
		CalcGivensValues( *(--wPtr), curSd, &c, &s );
		V.PostApplyGivens( c, -s, i, endIdx );
		*wPtr = c*(*wPtr) - s*curSd;
		if ( i==0 ) {
			break;
		}
		curSd = s*(*(--sdPtr));		// New value pops up one row above
		if ( NearZero( curSd, eps ) ) {
			break;
		}
		*sdPtr = c*(*sdPtr);
		i--;
	}
}
Ejemplo n.º 4
0
// set origin of pResult to the intersecting point
// of pL1, and pL2 assuming they are not skew
int FindIntersection( PVECTOR presult,
                       PVECTOR s1, PVECTOR o1, 
                       PVECTOR s2, PVECTOR o2 )
{
   VECTOR R1, R2, denoms;
   RCOORD t1, t2, denom;

#define a (o1[0])
#define b (o1[1])
#define c (o1[2])

#define d (o2[0])
#define e (o2[1])
#define f (o2[2])

#define na (s1[0])
#define nb (s1[1])
#define nc (s1[2])

#define nd (s2[0])
#define ne (s2[1])
#define nf (s2[2])

   crossproduct( denoms, s1, s2 );
   denom = denoms[2];
//   denom = ( nd * nb ) - ( ne * na );
   if( NearZero( denom ) )
   {
      denom = denoms[1];
//      denom = ( nd * nc ) - (nf * na );
      if( NearZero( denom ) )
      {
         denom = denoms[0];
//         denom = ( ne * nc ) - ( nb * nf );
         if( NearZero( denom ) )
         {
            SetPoint( presult, VectorConst_0 );
            return FALSE;
         }
         else
         {
            t1 = ( ne * ( f - c ) + nf * ( e - b ) ) / -denom;
            t2 = ( nb * ( c - f ) + nc * ( b - e ) ) / denom;
         }
      }
      else
      {
         t1 = ( nd * ( f - c ) + nf * ( d - a ) ) / -denom;
         t2 = ( na * ( c - f ) + nc * ( a - d ) ) / denom;
      }
   }
   else
   {
      t1 = ( nd * ( e - b ) + ne * ( d - a ) ) / -denom;
      t2 = ( na * ( b - e ) + nb * ( a - d ) ) / denom;
   }

   scale( R1, s1, t1 );
   add  ( R1, R1         , o1 );

   scale( R2, s2, t2 );
   add  ( R2, R2         , o2 );


   if( ( !COMPARE(R1[0] , R2[0]) ) ||
       ( !COMPARE(R1[1] , R2[1]) ) ||
       ( !COMPARE(R1[2] , R2[2]) ) )
   {
      SetPoint( presult, VectorConst_0 );
      return FALSE;
   }
   SetPoint( presult, R1);
   return TRUE;
#undef a
#undef b
#undef c
#undef d
#undef e
#undef f
#undef na
#undef nb
#undef nc
#undef nd
#undef ne
#undef nf
}
Ejemplo n.º 5
0
int FindIntersectionTime( RCOORD *pT1, PVECTOR s1, PVECTOR o1
                        , RCOORD *pT2, PVECTOR s2, PVECTOR o2 )
{
   VECTOR R1, R2, denoms;
   RCOORD t1, t2, denom;

#define a (o1[0])
#define b (o1[1])
#define c (o1[2])

#define d (o2[0])
#define e (o2[1])
#define f (o2[2])

#define na (s1[0])
#define nb (s1[1])
#define nc (s1[2])

#define nd (s2[0])
#define ne (s2[1])
#define nf (s2[2])

   crossproduct(denoms, s1, s2 ); // - result...
   denom = denoms[2];
//   denom = ( nd * nb ) - ( ne * na );
   if( NearZero( denom ) )
   {
      denom = denoms[1];
//      denom = ( nd * nc ) - (nf * na );
      if( NearZero( denom ) )
      {
         denom = denoms[0];
//         denom = ( ne * nc ) - ( nb * nf );
         if( NearZero( denom ) )
         {
#ifdef FULL_DEBUG
            sprintf( (char*)byBuffer,"Bad!-------------------------------------------\n");
            Log( (char*)byBuffer );
#endif
            return FALSE;
         }
         else
         {
            DebugBreak();
            t1 = ( ne * ( c - f ) + nf * ( b - e ) ) / denom;
            t2 = ( nb * ( c - f ) + nc * ( b - e ) ) / denom;
         }
      }
      else
      {
         DebugBreak();
         t1 = ( nd * ( c - f ) + nf * ( d - a ) ) / denom;
         t2 = ( na * ( c - f ) + nc * ( d - a ) ) / denom;
      }
   }
   else
   {
      // this one has been tested.......
      t1 = ( nd * ( b - e ) + ne * ( d - a ) ) / denom;
      t2 = ( na * ( b - e ) + nb * ( d - a ) ) / denom;
   }

   R1[0] = a + na * t1;
   R1[1] = b + nb * t1;
   R1[2] = c + nc * t1;

   R2[0] = d + nd * t2;
   R2[1] = e + ne * t2;
   R2[2] = f + nf * t2;

   if( ( !COMPARE(R1[0],R2[0]) ) ||
       ( !COMPARE(R1[1],R2[1]) ) ||
       ( !COMPARE(R1[2],R2[2]) ) )
   {
      return FALSE;
   }
   *pT2 = t2;
   *pT1 = t1;
   return TRUE;
#undef a
#undef b
#undef c
#undef d
#undef e
#undef f
#undef na
#undef nb
#undef nc
#undef nd
#undef ne
#undef nf
}
Ejemplo n.º 6
0
RENDER_NAMESPACE 

// intersection of lines - assuming lines are
// relative on the same plane....

//int FindIntersectionTime( RCOORD *pT1, LINESEG pL1, RCOORD *pT2, PLINE pL2 )

int FindIntersectionTime( RCOORD *pT1, PVECTOR s1, PVECTOR o1
                        , RCOORD *pT2, PVECTOR s2, PVECTOR o2 )
{
   VECTOR R1, R2, denoms;
   RCOORD t1, t2, denom;

#define a (o1[0])
#define b (o1[1])
#define c (o1[2])

#define d (o2[0])
#define e (o2[1])
#define f (o2[2])

#define na (s1[0])
#define nb (s1[1])
#define nc (s1[2])

#define nd (s2[0])
#define ne (s2[1])
#define nf (s2[2])

   crossproduct(denoms, s1, s2 ); // - result...
 PrintVector( denoms );
   denom = denoms[2];
//   denom = ( nd * nb ) - ( ne * na );
   if( NearZero( denom ) )
   {
      denom = denoms[1];
//      denom = ( nd * nc ) - (nf * na );
      if( NearZero( denom ) )
      {
         denom = denoms[0];
//         denom = ( ne * nc ) - ( nb * nf );
         if( NearZero( denom ) )
         {
#ifdef FULL_DEBUG
            lprintf("Bad!-------------------------------------------\n");
#endif
            return FALSE;
         }
         else
         {
            DebugBreak();
            t1 = ( ne * ( c - f ) + nf * ( b - e ) ) / denom;
            t2 = ( nb * ( c - f ) + nc * ( b - e ) ) / denom;
         }
      }
      else
      {
         DebugBreak();
         t1 = ( nd * ( c - f ) + nf * ( d - a ) ) / denom;
         t2 = ( na * ( c - f ) + nc * ( d - a ) ) / denom;
      }
   }
   else
   {
      // this one has been tested.......
      t1 = ( nd * ( b - e ) + ne * ( d - a ) ) / denom;
      t2 = ( na * ( b - e ) + nb * ( d - a ) ) / denom;
   }

   R1[0] = a + na * t1;
   R1[1] = b + nb * t1;
   R1[2] = c + nc * t1;

   R2[0] = d + nd * t2;
   R2[1] = e + ne * t2;
   R2[2] = f + nf * t2;

   if( ( !COMPARE(R1[0],R2[0]) ) ||
       ( !COMPARE(R1[1],R2[1]) ) ||
       ( !COMPARE(R1[2],R2[2]) ) )
   {
		PrintVector( R1 );
		PrintVector( R2 );
		lprintf( WIDE("too far from the same... %g %g "), t1, t2 );
      return FALSE;
   }
   *pT2 = t2;
   *pT1 = t1;
   return TRUE;
#undef a
#undef b
#undef c
#undef d
#undef e
#undef f
#undef na
#undef nb
#undef nc
#undef nd
#undef ne
#undef nf
}
Ejemplo n.º 7
0
// **************** ConvertBidiagToDiagonal ***********************************************
// Do the iterative transformation from bidiagonal form to diagonal form using
//		Givens transformation.  (Golub-Reinsch)
// U and V are square.  Size of U less than or equal to that of U.
void MatrixRmn::ConvertBidiagToDiagonal( MatrixRmn& U, MatrixRmn& V, VectorRn& w, VectorRn& superDiag ) const
{
	// These two index into the last bidiagonal block  (last in the matrix, it will be
	//	first one handled.
	long lastBidiagIdx = V.NumRows-1;
	long firstBidiagIdx = 0;
	double eps = 1.0e-15 * Max(w.MaxAbs(), superDiag.MaxAbs());

	while ( true ) {
		bool workLeft = UpdateBidiagIndices( &firstBidiagIdx, &lastBidiagIdx, w, superDiag, eps );
		if ( !workLeft ) {
			break;
		}

		// Get ready for first Givens rotation
		// Push non-zero to M[2,1] with Givens transformation
		double* wPtr = w.x+firstBidiagIdx;
		double* sdPtr = superDiag.x+firstBidiagIdx;
		double extraOffDiag=0.0;
		if ( (*wPtr)==0.0 ) {
			ClearRowWithDiagonalZero( firstBidiagIdx, lastBidiagIdx, U, wPtr, sdPtr, eps );
			if ( firstBidiagIdx>0 ) {
				if ( NearZero( *(--sdPtr), eps ) ) {
					*sdPtr = 0.0;
				}
				else {
					ClearColumnWithDiagonalZero( firstBidiagIdx, V, wPtr, sdPtr, eps );
				}
			}
			continue;
		}

		// Estimate an eigenvalue from bottom four entries of M
		// This gives a lambda value which will shift the Givens rotations
		// Last four entries of M^T * M are  ( ( A, B ), ( B, C ) ).
		double A;
		A = (firstBidiagIdx<lastBidiagIdx-1) ? Square(superDiag[lastBidiagIdx-2]): 0.0;
		double BSq = Square(w[lastBidiagIdx-1]);
		A += BSq;										// The "A" entry of M^T * M
		double C = Square(superDiag[lastBidiagIdx-1]);	
		BSq *= C;										// The squared "B" entry
		C += Square(w[lastBidiagIdx]);					// The "C" entry
		double lambda;									// lambda will hold the estimated eigenvalue
		lambda = sqrt( Square((A-C)*0.5) + BSq );		// Use the lambda value that is closest to C.
		if ( A > C ) {
			lambda = -lambda;
		}
		lambda += (A+C)*0.5;						// Now lambda equals the estimate for the last eigenvalue
		double t11 = Square(w[firstBidiagIdx]);
		double t12 = w[firstBidiagIdx]*superDiag[firstBidiagIdx];

		double c, s;
		CalcGivensValues( t11-lambda, t12, &c, &s );
		ApplyGivensCBTD( c, s, wPtr, sdPtr, &extraOffDiag, wPtr+1 );
		V.PostApplyGivens( c, -s, firstBidiagIdx );
		long i;
		for ( i=firstBidiagIdx; i<lastBidiagIdx-1; i++ ) {
			// Push non-zero from M[i+1,i] to M[i,i+2] 
			CalcGivensValues( *wPtr, extraOffDiag, &c, &s );
			ApplyGivensCBTD( c, s, wPtr, sdPtr, &extraOffDiag, extraOffDiag, wPtr+1, sdPtr+1 );
			U.PostApplyGivens( c, -s, i );
			// Push non-zero from M[i,i+2] to M[1+2,i+1]
			CalcGivensValues( *sdPtr, extraOffDiag, &c, &s );
			ApplyGivensCBTD( c, s, sdPtr, wPtr+1, &extraOffDiag, extraOffDiag, sdPtr+1, wPtr+2 );
			V.PostApplyGivens( c, -s, i+1 );
			wPtr++;
			sdPtr++;
		}
		// Push non-zero value from M[i+1,i] to M[i,i+1] for i==lastBidiagIdx-1
		CalcGivensValues( *wPtr, extraOffDiag, &c, &s );
		ApplyGivensCBTD( c, s, wPtr, &extraOffDiag, sdPtr, wPtr+1 );
		U.PostApplyGivens( c, -s, i );

		// DEBUG
		// DebugCalcBidiagCheck( V, w, superDiag, U );
	}
}
Ejemplo n.º 8
0
void SeasonalWindow::OnKeyboard(i32 key, bool down)
{
	if(key == VK_ESCAPE && down)
	{
		Close();
	}
	
	i32 _key = tolower(key);

	f32 dt = (f32)gxbase::App::GetDeltaTime();
	dt = min(dt, 0.02f); // workaround to help remove any jitters when dt jumps

	f32 cameraSpeed = 35;

	// Up, down, left and right arrows can be held. We use dt
	// to impact speed of rotations
	switch(_key)
	{
		case 37: // left arrow
		{
			scn.SetCameraRotation(scn.GetCameraRotation() - dt * cameraSpeed);
			break;
		}
	case 39: // right arrow
		{
			scn.SetCameraRotation(scn.GetCameraRotation() + dt * cameraSpeed);
			break;
		}
	case 38: // up arrow
		{
			scn.SetCameraAngle(scn.GetCameraAngle() - dt * cameraSpeed);
			break;
		}
	case 40: // down arrow
		{
			scn.SetCameraAngle(scn.GetCameraAngle() + dt * cameraSpeed);
			break;
		}
	}

	if(down) // all other keys must be released before they are registered
	{
		return;
	}

	switch(_key)
	{
	case 'h':
		{
			displayHelpMenu = !displayHelpMenu;
		} break;
	case 187: //+
		scn.SetDtMultiplier(scn.GetMultiplier() + 0.1);
		break;
	case 189: //-
		scn.SetDtMultiplier(scn.GetMultiplier() - 0.1);
		break;
	case 'p':
		{
			// application class as paused when dt multiplier 0 (accounting for floating point errors)
			// this is a better solution than an isPaused boolean variable, as the user can press + or -
			// to unpause the application, incrementing/ decrementing the multiplier by 0.1
			if(NearZero((f32)scn.GetMultiplier()))
			{
				scn.SetDtMultiplier(1);
			}
			else
			{
				scn.SetDtMultiplier(0);
			}
		} break;
	case 'm':
		{
			scn.SetTreeShadeMode(scn.GetNextTreeShadeMode());
		} break;
	case 's':
		{
			// Order: Directional - Spotlight - Ambient - Directional
			const LightingMode lm = scn.GetLightingMode();
			switch(lm)
			{
			case Directional: { scn.SetLightingMode(Spotlights); break; }
			case Spotlights: { scn.SetLightingMode(Ambient); break; }
			case Ambient: { scn.SetLightingMode(Directional); break; }
			}
		} break;
	case 't':
		{
			scn.SetPolygonMode(scn.GetNextPolygonMode(scn.GetPolygonMode()));
		};
	}
};