Beispiel #1
0
void PhysicsLoop( void )
{
  glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

  RenderString( 1, 2, "Left click to spawn a polygon" );
  RenderString( 1, 4, "Right click to spawn a circle" );

  static float accumulator = 0;
  accumulator += clock.Elapsed( );
  clock.Start( );

  accumulator = Clamp( 0.0f, 0.1f, accumulator );
  while(accumulator >= dt)
  {
    if(!frameStepping)
      scene.Step( );
    else
    {
      if(canStep)
      {
        scene.Step( );
        canStep = false;
      }
    }
    accumulator -= dt;
  }

  clock.Stop( );

  scene.Render( );

  glutSwapBuffers( );
}
void SpectralClustering::Cluster(const DenseMatrix<double> &S, UINT kMeansClusters, UINT reducedDimensionCount, Method method, Vector<UINT> &clusterIDs, SpectralClusteringCache *cache)
{
    const UINT pointCount = S.RowCount();
    
    Console::WriteLine("Spectral clustering on " + String(pointCount) + " points, " + String(kMeansClusters) + " clusters, " + String(reducedDimensionCount) + String(" dimensions"));
    
    DenseMatrix<double> L(pointCount, pointCount);
    MakeLaplacian(S, method, L);

    Vector<double> eigenvalues;
    DenseMatrix<double> eigenvectors;
    {
        if(cache != NULL && cache->eigenvalues.Length() == pointCount)
        {
            Console::WriteString("Loading eigensystem from cache...");
            eigenvalues = cache->eigenvalues;
            eigenvectors = cache->eigenvectors;
        }
        else
        {
            Clock timer;
            Console::WriteString("Solving eigensystem...");
            L.EigenSystemTNT(eigenvalues, eigenvectors);
            Console::WriteLine(String(timer.Elapsed()) + "s");
        }
        if(cache != NULL)
        {
            cache->eigenvalues = eigenvalues;
            cache->eigenvectors = eigenvectors;
        }
    }

    //
    // Note that the eigensystem is sorted in decreasing order.
    //
    const bool useLargestEigenvector = (method == RandomWalk || method == Symmetric);
    
    Vector<VecNf> points(pointCount);
    for(UINT pointIndex = 0; pointIndex < pointCount; pointIndex++)
    {
        VecNf &curPoint = points[pointIndex];
        curPoint.v.Allocate(reducedDimensionCount);
        for(UINT dimensionIndex = 0; dimensionIndex < reducedDimensionCount; dimensionIndex++)
        {
            if(useLargestEigenvector)
            {
                curPoint[dimensionIndex] = float(eigenvectors(pointIndex, pointCount - dimensionIndex - 1));
            }
            else
            {
                curPoint[dimensionIndex] = float(eigenvectors(pointIndex, dimensionIndex));
            }
            
        }
    }

    if(method == Symmetric)
    {
        for(UINT pointIndex = 0; pointIndex < pointCount; pointIndex++)
        {
            points[pointIndex] = VecNf::Normalize(points[pointIndex]);
        }
    }

    KMeansClustering<VecNf, VecNfKMeansMetric> clustering;
    clustering.Cluster(points, kMeansClusters, 100);
    
    clusterIDs.Allocate(pointCount);
    for(UINT pointIndex = 0; pointIndex < pointCount; pointIndex++)
    {
        clusterIDs[pointIndex] = clustering.QuantizeToNearestClusterIndex(points[pointIndex]);
    }
}