void gradient_descent(scene & mesh, physics & phys, int minbasecount, StoreBestFunctorT store_best_functor, RunningFunctorT running_functor) { scene::HelixContainer & helices(mesh.getHelices()); while (!mesh.isSleeping() && running_functor()) { phys.scene->simulate(1.0f / 60.0f); phys.scene->fetchResults(true); } //physics::real_type separation(mesh.getTotalSeparation()); physics::real_type min, max, average, total; mesh.getTotalSeparationMinMaxAverage(min, max, average, total); store_best_functor(mesh, min, max, average, total); for (Helix & helix : helices) { for (int i = 0; i < 2; ++i) { if (!running_functor()) return; helix.recreateRigidBody(phys, std::max(minbasecount, int(helix.getInitialBaseCount() + (i * 2 - 1))), helix.getInitialTransform()); while (!mesh.isSleeping() && running_functor()) { phys.scene->simulate(1.0f / 60.0f); phys.scene->fetchResults(true); } //const physics::real_type newseparation(mesh.getTotalSeparation()); physics::real_type newtotal; mesh.getTotalSeparationMinMaxAverage(min, max, average, newtotal); if (newtotal < total) { total = newtotal; store_best_functor(mesh, min, max, average, total); } else helix.recreateRigidBody(phys, helix.getInitialBaseCount(), helix.getInitialTransform()); for (Helix & helix : helices) helix.setTransform(helix.getInitialTransform()); } } }
void simulated_annealing(scene & mesh, physics & phys, int kmax, float emax, unsigned int minbasecount, int baserange, StoreBestFunctorT store_best_functor, RunningFunctorT running_functor) { int modifiedHelix, previousBaseCount; physics::transform_type previousTransform; scene::HelixContainer & helices(mesh.getHelices()); const scene::HelixContainer::size_type helixCount(helices.size()); simulated_annealing(mesh, [](scene & mesh) { return mesh.getTotalSeparation(); }, [&helixCount](float k) { return float(std::max(0., (exp(-k) - 1 / M_E) / (1 - 1 / M_E))) * helixCount; }, [&modifiedHelix, &helices, &helixCount, &previousBaseCount, &previousTransform, &phys, &minbasecount, &baserange, &running_functor](scene & mesh) { for (Helix & helix : helices) helix.setTransform(helix.getInitialTransform()); modifiedHelix = rand() % helixCount; Helix & helix(helices[modifiedHelix]); previousBaseCount = helix.getBaseCount(); previousTransform = helix.getTransform(); helix.recreateRigidBody( phys, std::max(minbasecount, helix.getInitialBaseCount() + (rand() % 2 * 2 - 1) * (1 + rand() % (baserange))), helix.getInitialTransform()); while (!mesh.isSleeping() && running_functor()) { phys.scene->simulate(1.0f / 60.0f); phys.scene->fetchResults(true); } }, probability_functor<float, float>(), [&modifiedHelix, &helices, &previousBaseCount, &previousTransform, &phys](scene & mesh) { Helix & helix(helices[modifiedHelix]); helix.recreateRigidBody(phys, previousBaseCount, helix.getInitialTransform()); }, store_best_functor, running_functor, kmax, emax); }
void display(){ int i; float angulo; glClear(GL_COLOR_BUFFER_BIT); /*Primero dibujo el piso*/ glColor3f(0.22,0.49,0.01); glBegin(GL_POLYGON); glVertex2i(0,width/8); glVertex2i(0,0); glVertex2i(width,0); glVertex2i(width,height/8); glEnd(); /*Dibujo la pista*/ glColor3f(0.27,0.32,0.24); glBegin(GL_POLYGON); glVertex2i(0,height/4); glVertex2i(0,height/8); glVertex2i(width,height/8); glVertex2i(width,height /4); glEnd(); /*Los cerros*/ glColor3f(0.22,0.49,0.01); glBegin(GL_POLYGON); glVertex2i(0,height/4); glVertex2i(width,height/4); glVertex2i(width,5*height/16); glVertex2i(width*7/8,3*height/8); glVertex2i(width*3/4,5*height/16); glVertex2i(width/3,5*height/8); glVertex2i(width/3,height/4); glEnd(); glColor3f(0.22,0.49,0.01); glBegin(GL_POLYGON); glVertex2i(0,height/4); glVertex2i(0,height*3/8); glVertex2i(width/8,height/2); glVertex2i(width/4,height/4); glEnd(); /*Las lineas de la pista*/ glColor3f(1.0,1.0,1.0); glBegin(GL_POLYGON); glVertex2i(0,3*height/16); glVertex2i(width,3*height/16); glVertex2i(width,13*height/64); glVertex2i(0,13*height/64); glEnd(); /*Lineas del sol*/ for(i = 0 ; i < 18 ; i++){ // angulo = glColor3f(1.0,1.0,0.0); glLineWidth(3); glBegin(GL_LINES); glVertex2f(3*width/4,4*height/5); glVertex2f( (3*width/4) + (width*cos(20*2*PI*i/360)/8),(4*height/5) + (width*sin(20*2*PI*i/360)/8)); glEnd(); } /* EL sol*/ glColor3f(1.0,0.0,0.0); circulo(width/16,3*width/4,4*height/5); glColor3f(1.0,1.0,0.0); circulo(15*width/256,3*width/4,4*height/5); /*Las helices*/ helices(width/16,3*height/8,3*height/4); helices(3*width/10,height/2,3*height/4); helices(width/2,5*height/16,3*height/4); /*dibuja el carro*/ carro(); glutSwapBuffers(); glFlush(); }