summaryrefslogtreecommitdiff
path: root/animation.hpp
blob: 5c9f6693087b206f51e64671ece900b5d4b6157b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111

#include "space_wolff.hpp"
#include <GL/glut.h>

template <typename T, int D>
void drawSphere(const Vector<T, D>& x, Radius r, std::array<double, 3> color = {0, 0, 0},
                unsigned nPoints = 20) {
  glColor3d(color[0], color[1], color[2]);
  glBegin(GL_POLYGON);
  for (unsigned i = 0; i < nPoints; i++) {
    glVertex2d(x(0) + r * cos(2 * i * M_PI / nPoints), x(1) + r * sin(2 * i * M_PI / nPoints));
  }
  glEnd();
}

template <typename T, int D>
void draw(const Spin<T, D, Radius>& s, std::array<double, 3> color = {0, 0, 0}) {
  drawSphere<T, D>(s.x, s.s, color);
}

template <typename T, int D>
void draw(const Spin<T, D, Dimer<T, D>>& s, std::array<double, 3> color = {0, 0, 0}) {
  drawSphere<T, D>(s.x + s.s.relativePosition, s.s.radius, color);
  drawSphere<T, D>(s.x - s.s.relativePosition, s.s.radius, color);
}

template <int D>
void draw(const Spin<signed, D, IsingSpin>& s, std::array<double, 3> color = {0, 0, 0}) {
  if (s.s == 1) {
    glColor3d(color[0], color[1], color[2]);
  } else if (s.s == -1) {
    glColor3d(1 - color[0], 1 - color[1], 1 - color[2]);
  }
  glRecti(s.x(0), s.x(1), s.x(0) + 1, s.x(1) + 1);
}

template <typename T, int D, class R, class S> class Animation : public measurement<T, D, R, S> {
private:
  unsigned n;
  unsigned wait;
  double L;
  R s₀⁻¹;

public:
  Animation(T L, unsigned w, int argc, char* argv[], unsigned wait, bool periodic = false)
      : s₀⁻¹(L), wait(wait), L(1000 * L) {
    n = 0;

    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowSize(w, w);
    glutCreateWindow("wolffWindow");
    glClearColor(0.0, 0.0, 0.0, 0.0);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    if (periodic) {
      gluOrtho2D(0, L, 0, L);
    } else {
      gluOrtho2D(-L, L, -L, L);
    }
  }

  void pre_cluster(const Model<T, D, R, S>& m, unsigned,
                   const Transformation<T, D, R, S>* t) override {
    s₀⁻¹ = m.s0.inverse();
    glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    for (const Spin<T, D, S>* s : m.s) {
      draw(s₀⁻¹.act(*s));
    }
    if (n > wait) {
      glColor3d(1.0, 0.0, 0.0);
      glLineWidth(3);
      glBegin(GL_LINES);
      Vector<T, D> r = t->r.t / 2;
      double θ = atan2(r(1), r(0));
      Vector<T, D> v1 = s₀⁻¹.act({r(0) + L * sin(θ), r(1) - L * cos(θ)});
      Vector<T, D> v2 = s₀⁻¹.act({r(0) - L * sin(θ), r(1) + L * cos(θ)});
      glVertex2d(v1(0), v1(1));
      glVertex2d(v2(0), v2(1));
      glEnd();
    }
    glFlush();
  }

  void plain_site_transformed(const Model<T, D, R, S>& m,
                              const Transformation<T, D, R, S>& t) override {
    if (n > wait) {
      std::array<double, 3> color;
      if (t.current().size() > 1) {
        color = {0, 0, 1};
      } else {
        color = {0, 1, 0};
      }
      for (const Spin<T, D, S>* s : t.current()) {
        if (s != NULL) {
          draw(s₀⁻¹.act(*s), color);
        } else {
        }
      }
    }
  }

  void post_cluster(const Model<T, D, R, S>& m) override {
    if (n > wait) {
      glFlush();
      sleep(2);
    }
    n++;
  }
};