void Engine::iterBuildPoints( const Skeleton& skelet, const Zoom& zoom, Image& image, const int imax ) const { if ( Function::system == LINEAR ) { for ( int i = 1; i <= imax; ++i ) { skelet.nextPoint( _x, _y, _color ); zoom.toScreen( _x, _y ); image.mem_plot( zoom.screenX, zoom.screenY ); image.mem_coul( zoom.screenX, zoom.screenY, _color ); } } else if ( Function::system == FORMULA || Function::system == SINUSOIDAL ) { // since initial conditions are important, we have to give a new seed to the orbit _x = (float)rand()*2/RAND_MAX - 1; _y = (float)rand()*2/RAND_MAX - 1; skelet.setXY( _x, _y, _color ); // put the seed in the orbit for ( int i = 1; i <= imax; ++i ) { skelet.nextPoint( _x, _y, _color ); zoom.toScreen( _x, _y ); image.mem_plot( zoom.screenX, zoom.screenY ); image.mem_coul( zoom.screenX, zoom.screenY, _color ); if ( i % 1000 == 0 ) { _x = (float)rand()*2/RAND_MAX - 1; _y = (float)rand()*2/RAND_MAX - 1; skelet.setXY( _x, _y, _color ); } } } else { // JULIA Julia& j = zoom.julia; for ( int i = 1; i <= imax; ++i ) { skelet.nextPoint( _x, _y, _color ); zoom.toScreen( _x, _y ); j.handle( _x, _y, image.getHit( zoom.screenX, zoom.screenY ) ); image.mem_plot( zoom.screenX, zoom.screenY ); image.mem_coul( zoom.screenX, zoom.screenY, _color ); } } }
void Engine::zoom() { const int imagesWidth = ( state == SAVEMNG ) ? animationSavedWidth : w(); const int imagesHeight = ( state == SAVEMNG ) ? animationSavedHeight : h(); Skeleton skelSubframe; // we must check that we are not going to zoom inside the zoom function: if ( skel.selected() == 0 ) { // this section should be synchronized since the selected function // can be changed before its use by Skeleton::subframe skel.shiftSelectedFunction(1); } skelSubframe.subframe(skel); Function functionWork; const Zoom zoom( skel.findFrame( pointsForFraming, _x, _y, _color ), imagesWidth, imagesHeight, skel.getZoomFunction(), framesPerCycle ); for ( std::vector< Image* >::const_iterator i = images.begin(); i != images.end(); ++i ) { delete *i; } images.clear(); for ( int i = 0; i < framesPerCycle; ++i ) { images.push_back( buildImage( imagesWidth, imagesHeight, w(), h() ) ); } int idemo = 1; const int idemoMax = 3; unsigned long clock0 = clock(); const float dilat0 = 1.0/skelSubframe.getFunction().surface(); const float dilat1 = 1.0/skel.getFunction().surface(); const float otherDilat = 1.0/(skel.sumSurfaces() - skel.getFunction().surface()); while ( idemo <= idemoMax ) { for ( int k = 0; k < framesPerCycle; ++k ) { const float rate = (float)k / framesPerCycle; functionWork.spiralMix( skel.getFunction(), skelSubframe.getFunction(), rate ); functionWork.calculateTemp(); int pointsToCalculate = pointsPerFrame; if ( state == SAVEMNG) { // points(t) = points(0)*(1 + S/s(t) * (1/s(t) - 1/s(0))/(1/s(1) - 1/s(0)) ) pointsToCalculate = (int)( ( 1.0 + (1/functionWork.surface()-dilat0) / (dilat1-dilat0) * dilat1 / otherDilat ) * pointsPerFrame ); // to avoid explosion of computation time: if ( pointsToCalculate > 100 * pointsPerFrame ) { pointsToCalculate = 100 * pointsPerFrame; } } for ( int i = 1; clockNumber || i < pointsToCalculate; ++i ) { skel.nextPoint( _x, _y, _color ); float zx = _x; float zy = _y; functionWork.previousPoint( zx, zy, false ); zoom.toScreen( zx, zy ); images[k]->mem_plot( zoom.screenX, zoom.screenY ); images[k]->mem_coul( zoom.screenX, zoom.screenY, _color ); if ( clockNumber ) { if ( i % minimalBuiltPoints == 0 ) { const unsigned long newClock = clock(); if ( newClock - clock0 >= intervalFrame * timecv ) { clock0 = newClock; break; } } } } make_current(); images[k]->mem_draw(); if ( Fl::ready() ) { Fl::check(); } if ( state != ANIMATION && state != DEMO && state != SAVEMNG ) { return; } } if ( state == DEMO ) { ++idemo; } if ( state == SAVEMNG ) { return; } } }