Advertisement
Guest User

Untitled

a guest
Apr 20th, 2019
151
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.24 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <math.h>
  5. #include <ncurses.h>
  6.  
  7. #define REALLOC_STRIDE 0x40
  8.  
  9. enum { X, Y, Z, Ndim };
  10.  
  11. typedef struct {
  12.     double (*edge)[2][Ndim];
  13.     int numedges, resedges;
  14.     double xang, yang;
  15. } model_t;
  16.  
  17. void loop(model_t *);
  18. model_t *model_new(FILE *);
  19. void model_delete(model_t *);
  20. void model_addedge(model_t *, double, double, double, double, double, double);
  21. void model_rotate(model_t *, double, double);
  22. void model_print(model_t *, double, double, double);
  23.  
  24. int main(int argc, char **argv)
  25. {
  26.     FILE *file = fopen(argv[1], "r");
  27.     model_t *model = model_new(file);
  28.     fclose(file);
  29.  
  30.     initscr();
  31.     cbreak();
  32.     noecho();
  33.  
  34.     loop(model);
  35.     model_delete(model);
  36.  
  37.     echo();
  38.     nocbreak();
  39.     endwin();
  40. }
  41.  
  42. void loop(model_t *model)
  43. {
  44.     timeout(0);
  45.  
  46.     double dist = 100, zoom = 100;
  47.     while (1) {
  48.         napms(100);
  49.         int key;
  50.         while ((key = getch()) != ERR) {
  51.             switch (key) {
  52.                 case 'q': dist += 5; break;
  53.                 case 'a': dist -= 5; break;
  54.                 case 'w': zoom *= 1.125; break;
  55.                 case 's': zoom /= 1.125; break;
  56.                 case 'e': model_rotate(model, 0.0,  0.1); break;
  57.                 case 'd': model_rotate(model, 0.0, -0.1); break;
  58.                 case 'x': goto nahui;
  59.             }
  60.         }
  61.         model_rotate(model, 0.1, 0.0);
  62.         model_print(model, dist, zoom, 0.5);
  63.     }
  64.     nahui:
  65.  
  66.     timeout(-1);
  67. }
  68.  
  69. model_t *model_new(FILE *file)
  70. {
  71.     model_t *this = malloc(sizeof(model_t));
  72.  
  73.     this->edge = malloc(REALLOC_STRIDE * sizeof(*this->edge));
  74.     this->numedges = 0;
  75.     this->resedges = REALLOC_STRIDE;
  76.     this->yang = this->xang = 0;
  77.  
  78.     double x0, y0, z0, x1, y1, z1;
  79.     while (fscanf(file, "%lf%lf%lf%lf%lf%lf", &x0, &y0, &z0, &x1, &y1, &z1) == 6)
  80.     {
  81.         model_addedge(this, x0, y0, z0, x1, y1, z1);
  82.     }
  83.  
  84.     return this;
  85. }
  86.  
  87. void model_delete(model_t *this)
  88. {
  89.     free(this->edge);
  90.     free(this);
  91. }
  92.  
  93. void model_addedge(model_t *this,
  94.                    double x0, double y0, double z0,
  95.                    double x1, double y1, double z1)
  96. {
  97.     if (this->numedges == this->resedges) {
  98.         this->edge = realloc(this->edge, (this->resedges += REALLOC_STRIDE)
  99.                                          * sizeof(*this->edge));
  100.     }
  101.     this->edge[this->numedges][0][X] = x0;
  102.     this->edge[this->numedges][0][Y] = y0;
  103.     this->edge[this->numedges][0][Z] = z0;
  104.     this->edge[this->numedges][1][X] = x1;
  105.     this->edge[this->numedges][1][Y] = y1;
  106.     this->edge[this->numedges][1][Z] = z1;
  107.     ++this->numedges;
  108. }
  109.  
  110. void model_rotate(model_t *this, double yang, double xang)
  111. {
  112.     this->yang += yang;
  113.     this->xang += xang;
  114. }
  115.  
  116. void model_print(model_t *this, double dist, double zoom, double aspect)
  117. {
  118.     erase();
  119.     move(0, 0);
  120.     for (int i = 0; i < this->numedges; ++i) {
  121.         double xcos = cos(this->xang),
  122.                xsin = sin(this->xang),
  123.                ycos = cos(this->yang),
  124.                ysin = sin(this->yang),
  125.                x0t = ycos * this->edge[i][0][X] + ysin * this->edge[i][0][Z],
  126.                y0t = this->edge[i][0][Y],
  127.                z0t = ycos * this->edge[i][0][Z] - ysin * this->edge[i][0][X],
  128.                x0 = x0t,
  129.                y0 = xcos * y0t + xsin * z0t,
  130.                z0 = xcos * z0t - xsin * y0t + dist,
  131.                x1t = ycos * this->edge[i][1][X] + ysin * this->edge[i][1][Z],
  132.                y1t = this->edge[i][1][Y],
  133.                z1t = ycos * this->edge[i][1][Z] - ysin * this->edge[i][1][X],
  134.                x1 = x1t,
  135.                y1 = xcos * y1t + xsin * z1t,
  136.                z1 = xcos * z1t - xsin * y1t + dist;
  137.  
  138.         if (z0 < 5 || z1 < 5) continue;
  139.  
  140.         int cx = getmaxx(stdscr) / 2,
  141.             cy = getmaxy(stdscr) / 2,
  142.             x0_ = cx + zoom * x0 / z0,
  143.             y0_ = cy + zoom * y0 / z0 * aspect,
  144.             x1_ = cx + zoom * x1 / z1,
  145.             y1_ = cy + zoom * y1 / z1 * aspect,
  146.             len = (abs(x0_ - x1_) > abs(y0_ - y1_)) ? abs(x0_ - x1_) : abs(y0_ - y1_);
  147.         for (int p = 0; p <= len; ++p)
  148.             mvaddch(y0_ + (y1_ - y0_) * p / len, x0_ + (x1_ - x0_) * p / len, '$');
  149.     }
  150.     refresh();
  151. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement