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]); } }