ForrestFox

MandelFrac

Feb 21st, 2021 (edited)
226
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.06 KB | None | 0 0
  1. #include <qblib.c>
  2.  
  3. #define CHECKPOINT_NUMBER 7
  4.  
  5. static const double checkpoint[ CHECKPOINT_NUMBER ][ 2 ] = {
  6.  
  7.     {-0.373972789840348263101788006679271347820758819580,  0.659771146748583614538574693142436444759368896484}, // 0
  8.     { 0.368223619982562921926216858992120251059532165527,  0.592964429003537407680823889677412807941436767578}, // 1
  9.     {-1.942948951698288073686171628651209175586700439453,  0.000000000000000027818939071799278620520511283696}, // 2
  10.     {-0.027116964259834751282962628238237812183797359467,  0.808631325719216142999812291236594319343566894531}, // 3
  11.     { 0.250642464452859869972201067866990342736244201660, -0.000023159465316861627224177128114845913842145819}, // 4
  12.     {-0.747957199489194812791481581371044740080833435059,  0.075173326380023136605856848291296046227216720581}, // 5
  13.     {-1.942550688048265028484706817835103720426559448242,  0.000000441805744265319442252526547371127563224036}, // 6
  14. };
  15.  
  16. // Расчет фрактала
  17. int mandel(double cx, double cy) {
  18.  
  19.     double x = 0, y = 0;
  20.     for (int i = 0; i < 256; i++) {
  21.  
  22.         double tx = x*x - y*y + cx,
  23.                ty = 2*x*y     + cy;
  24.  
  25.         x = tx;
  26.         y = ty;
  27.  
  28.         if (x*x + y*y >= 4) return i;
  29.     }
  30.  
  31.     return 255;
  32. }
  33.  
  34. int main(int argc, char* argv[]) {
  35.  
  36.     screen(13);
  37.  
  38.     // Палитра
  39.     for (int i = 2; i < 256; i++) palette(i, i, i, 128 + (i>>1));
  40.     palette(0, 0, 0,   0);
  41.     palette(1, 0, 255, 0);
  42.     qb_scroll_x = 0;
  43.  
  44.     int     ip = 0; // CHECKPOINT_NUMBER - 1;
  45.     double  x0 = checkpoint[ip][0],
  46.             y0 = checkpoint[ip][1],
  47.             f  = ip ? 0.00000000000001 : 1;
  48.     double  dx = 0, dy = 0;
  49.     int     mx = -1, my = -1, st = -1;
  50.  
  51.     // Скорость приближения
  52.     float   speed = 0,
  53.             speed_prev = 0;
  54.     int     checkpoint_id = 0;
  55.     int     iter   = 0;
  56.     int     record = 1;
  57.  
  58.     // Черная подложка
  59.     linebf(0, 192, 319, 199, 0);
  60.  
  61.     load_running_string("ticker.txt");
  62.  
  63.     while (sdlevent(EVT_REDRAW)) {
  64.  
  65.         // Срабатывает событие
  66.         if (mouse.st == st && record == 0)
  67.             continue;
  68.  
  69.         mx = mouse.x;
  70.         my = mouse.y;
  71.  
  72.         double xm = (float)(mx - 160) / 100.0;
  73.         double ym = (float)(100 - my) / 100.0;
  74.  
  75.         // Режим записи видео
  76.         if (record) {
  77.  
  78.             // Если дно не было достигнуто, постепенно увеличивать скорость
  79.             if (f > 0.00000000000015)
  80.                  speed += 0.01;
  81.             // Достигнув дна, начинать разгон в обратную сторону с бОльшей скоростью для буста
  82.             else speed -= 0.06;
  83.  
  84.             // Точка перегиба из отдаления к приближению
  85.             if (speed_prev < 0 && speed > 0) {
  86.  
  87.                 checkpoint_id++;
  88.  
  89.                 // Следующий чекпоинт
  90.                 if (checkpoint_id < CHECKPOINT_NUMBER) {
  91.  
  92.                     iter = 100;
  93.                     dx   = (checkpoint[ checkpoint_id ][0] - x0) / (double)iter;
  94.                     dy   = (checkpoint[ checkpoint_id ][1] - y0) / (double)iter;;
  95.                 }
  96.                 else {
  97.                     record = 0;
  98.                 }
  99.             }
  100.  
  101.             // Линейное движение к другому чекпоинту
  102.             if (iter) {
  103.  
  104.                 x0 += dx;
  105.                 y0 += dy;
  106.  
  107.                 // Достигло конечного значения
  108.                 if (--iter == 0) {
  109.                     x0 = checkpoint[ checkpoint_id ][0];
  110.                     y0 = checkpoint[ checkpoint_id ][1];
  111.                 }
  112.             }
  113.  
  114.             f *= ((100.0 - speed)/100.0);
  115.             speed_prev = speed;
  116.         }
  117.         // Приближение
  118.         else if ((mouse.st & LF_CLICK) && !(st & LF_CLICK)) {
  119.  
  120.             x0  += f*xm;
  121.             y0  += f*ym;
  122.             f   /= 2.0;
  123.  
  124.             printf("{%.48f, %.48f}\n", x0, y0);
  125.         }
  126.         // Отдаление
  127.         else if ((mouse.st & RT_CLICK) && !(st & RT_CLICK)) {
  128.             f *= 2.0;
  129.         }
  130.  
  131.         // Перерисовать фрактал
  132.         for (int y = -91;  y <= 100; y++)
  133.         for (int x = -160; x <  160; x++) {
  134.  
  135.             double vx = x0 + f*(double)x / 100.0;
  136.             double vy = y0 + f*(double)y / 100.0;
  137.  
  138.             int cl = mandel(vx, vy);
  139.             pset(160 + x, 100 - y, cl < 2 ? 2 : cl);
  140.         }
  141.  
  142.         st = mouse.st;
  143.  
  144.         // HUD
  145.         line(160, 98, 160, 102, 128);
  146.         line(158, 100, 162, 100, 128);
  147.  
  148.         // Бегущая строка
  149.         color(255, 0); step_runstr(24);
  150.  
  151.         // -------------------------------------------------------------
  152.         if (record) record2ppm("record");
  153.  
  154.         // Отладочный
  155.         color(1, -1); locate (0, 0); print("#"); print(itoa(checkpoint_id));
  156.         color(1, -1); locate (0, 1); print(itoa(rec_frame_id));
  157.     }
  158.  
  159.     return 0;
  160. }
  161.  
Add Comment
Please, Sign In to add comment