Advertisement
runewalsh

[xynta] turbulent line

Mar 2nd, 2013
369
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.43 KB | None | 0 0
  1. // asd.cpp : Defines the entry point for the console application.
  2. //
  3.  
  4. #include "stdafx.h"
  5. #include "windows.h"
  6. #include <time.h>
  7. #include <math.h>
  8. #include <conio.h>
  9. #define clamp(x, a, b) min(max(x, a), b);
  10.  
  11. class Console
  12. {
  13. private:
  14.     HANDLE handle;
  15.     int width, height;
  16. public:
  17.     Console() : handle(GetStdHandle(STD_OUTPUT_HANDLE)), width(80), height(25)
  18.     {
  19.     }
  20.  
  21.     void put(int x, int y, int ch)
  22.     {
  23.         if ((x < 0) || (y < 0) || (x >= width) || (y >= height))
  24.             return;
  25.  
  26.         COORD pos;
  27.         pos.X = x, pos.Y = y;
  28.         SetConsoleCursorPosition(handle, pos);
  29.         putchar(ch);
  30.     }
  31. };
  32.  
  33. Console console;
  34.  
  35. float randf()
  36. {
  37.     return (float)rand() / (float)RAND_MAX;
  38. }
  39.  
  40. float signf(float x)
  41. {
  42.     return (x > 0.0) ? 1.0f : (x < 0.0) ? -1.0f : 0.0f;
  43. }
  44.  
  45. void turbulent_line_impl(int curX, int curY, int targetX, int targetY, float turb_coef, int ch, int guard)
  46. {
  47.     console.put(curX, curY, ch);
  48.     if ((curX == targetX) && (curY == targetY))
  49.         return;
  50.  
  51.     enum Direction { LEFT, RIGHT, UP, DOWN, LUP, RUP, LDOWN, RDOWN, N_DIRECTIONS };
  52.     Direction dir;
  53.     if (guard > 0)
  54.     {
  55.         guard--;
  56.         float dx = (float)(targetX - curX);
  57.         float dy = (float)(targetY - curY);
  58.         float raw_proba_up = max((dx != 0.0) ? -dy / fabs(dx) : signf(-dy), 0.0f);
  59.         float raw_proba_dn = max((dx != 0.0) ?  dy / fabs(dx) : signf(dy),  0.0f);
  60.         float raw_proba_lt = max((dy != 0.0) ? -dx / fabs(dy) : signf(-dx), 0.0f);
  61.         float raw_proba_rt = max((dy != 0.0) ?  dx / fabs(dy) : signf(dx),  0.0f);
  62.         float proba_up  =             raw_proba_up;
  63.         float proba_dn  = proba_up  + raw_proba_dn;
  64.         float proba_lt  = proba_dn  + raw_proba_lt;
  65.         float proba_rt  = proba_lt  + raw_proba_rt;
  66.         float proba_lup = proba_rt  + (float)_hypot(raw_proba_lt, raw_proba_up);
  67.         float proba_ldn = proba_lup + (float)_hypot(raw_proba_lt, raw_proba_dn);
  68.         float proba_rup = proba_ldn + (float)_hypot(raw_proba_rt, raw_proba_up);
  69.         float proba_sum = proba_rup + (float)_hypot(raw_proba_rt, raw_proba_dn);
  70.  
  71.         if (randf() < turb_coef * proba_sum)
  72.             dir = (Direction)(rand() % N_DIRECTIONS);
  73.         else
  74.         {
  75.             float rn = randf() * proba_sum;
  76.             dir =
  77.                 (rn < proba_up) ? UP :
  78.                 (rn < proba_dn) ? DOWN :
  79.                 (rn < proba_lt) ? LEFT :
  80.                 (rn < proba_rt) ? RIGHT :
  81.                 (rn < proba_lup) ? LUP :
  82.                 (rn < proba_ldn) ? LDOWN :
  83.                 (rn < proba_rup) ? RUP :
  84.                 RDOWN;
  85.         }
  86.     } else
  87.     {
  88.         dir =
  89.             (targetX > curX) ?
  90.                 (targetY > curY) ? RDOWN : (targetY < curY) ? RUP : RIGHT :
  91.             (targetX < curX) ?
  92.                 (targetY > curY) ? LDOWN : (targetY < curY) ? LUP : LEFT :
  93.             (targetY > curY) ? DOWN : UP;
  94.     }
  95.  
  96.     switch (dir)
  97.     {
  98.         case UP:    curY--; break;
  99.         case DOWN:  curY++; break;
  100.         case LEFT:  curX--; break;
  101.         case RIGHT: curX++; break;
  102.         case LUP:   curX--, curY--; break;
  103.         case LDOWN: curX--, curY++; break;
  104.         case RUP:   curX++, curY--; break;
  105.         case RDOWN: curX++, curY++; break;
  106.     }
  107.     turbulent_line_impl(curX, curY, targetX, targetY, turb_coef, ch, guard);
  108. }
  109.  
  110. void turbulent_line(int curX, int curY, int targetX, int targetY, int ch, float turb_coef = 0.3)
  111. {
  112.     int guard = 5 * (1 + abs(curX - targetX) + abs(curY - targetY));
  113.     turb_coef = 0.125f * clamp(turb_coef, 0.0f, 1.0f);
  114.     turbulent_line_impl(curX, curY, targetX, targetY, turb_coef, ch, guard);
  115. }
  116.  
  117. int _tmain(int argc, _TCHAR* argv[])
  118. {
  119.     srand((unsigned int)time(0));
  120.    
  121.     const int N = 3;
  122.     const unsigned char syms[N] = {'#', '*', '@'};
  123.     for (int i = 0; i < N; i++)
  124.         turbulent_line(10, 10, 60, 20, syms[i]);
  125.  
  126.     _getch();
  127.     return 0;
  128. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement