(GLUT)ランドルト環風図形


アニメ『ポプテピピック』

小さい方がポプ子、背の高い方がピピ美というらしいです。まれに見るクソアニメかと思います。他アニメのパロディもあるので、なんのパロディかわからず何度も見て時間を浪費してしまいました。何故でしょう。面白くないことが分かっているのに、毎週必ず見てしまいます。あ、でも、毎回新コーナーのボブネミミッミは、本気で笑ってしまってるかもしれない。そしてボブネミミッミのポプ子とピピ美は目がキラキラしてるので可愛いかもしれない。
視力検査をした方が良いかもしれません。

視力検査で使うCのマークは、ランドルト環というマークらしいです。厳密なサイズはよくわからないので、ランドルト環風マークということで、GLUTで作ってみます。

マークの作り方ですが、以下のように円二つと四角一つだけで描けます。

ソースです。

takk@deb9:~$ cat -n eyetest.c
     1  #include <GL/glut.h>
     2  #include <math.h>
     3
     4  #define DEG2RAD(deg) deg * 2.0 * M_PI / 360.0
     5  #define WHITE 1.0, 1.0, 1.0, 0.0
     6  #define BLACK 0.0, 0.0, 0.0, 0.0
     7
     8  GLdouble size=0.8;
     9

色は白と黒のみ。sizeは画面の80%の直径の円からスタートします。

    10  void polygon(GLdouble x, GLdouble y, int n, GLdouble r)
    11  {
    12          GLdouble xx, yy, rr;
    13          int i;
    14          double deg;
    15
    16          glBegin(GL_POLYGON);
    17          glColor4f(BLACK);
    18
    19          for(i=0; i<n; i++){
    20                  deg = (360.0/n) * i;
    21                  xx = x + r * cos(DEG2RAD(deg));
    22                  yy = y + r * sin(DEG2RAD(deg));
    23                  glVertex2d(xx, yy);
    24          }
    25          glEnd();
    26

外側の円です。

    27          glBegin(GL_POLYGON);
    28          glColor4f(WHITE);
    29          deg = (360.0/4) * (rand()%4);
    30          xx = x + r * 0.78 * cos(DEG2RAD(deg));
    31          yy = y + r * 0.78 * sin(DEG2RAD(deg));
    32          rr = r * 0.22;
    33          glVertex2d(xx-rr, yy+rr);
    34          glVertex2d(xx-rr, yy-rr);
    35          glVertex2d(xx+rr, yy-rr);
    36          glVertex2d(xx+rr, yy+rr);
    37          glEnd();
    38

上下左右、どの位置に切れ目を入れるかは、乱数で決めることにします。
rand()%4なので、0~3の整数となり、対応する角度(0°90°180°270°)が決まります。

    39          glBegin(GL_POLYGON);
    40          glColor4f(WHITE);
    41          for(i=0; i<n; i++){
    42                  deg = (360.0/n) * i;
    43                  xx = x + r * 0.6 * cos(DEG2RAD(deg));
    44                  yy = y + r * 0.6 * sin(DEG2RAD(deg));
    45                  glVertex2d(xx, yy);
    46          }
    47          glEnd();
    48  }
    49

内側の白い円です。

    50  void callback_display()
    51  {
    52          glClearColor(WHITE);
    53          glClear(GL_COLOR_BUFFER_BIT);
    54
    55          polygon( 0.0, 0.0, 30, size);
    56          size *= 0.9;
    57
    58          glFlush();
    59  }
    60

タイマーがコールバックされる度にsizeは90%のサイズに縮小するようにします。

    61  void callback_timer(int value)
    62  {
    63          glutPostRedisplay();
    64          glutTimerFunc(3000,callback_timer,0);
    65  }
    66

3秒毎のタイマーです。コールバックされたら、再度タイマー発行が必要です。

    67  int main(int argc, char *argv[])
    68  {
    69          glutInit(&argc, argv);
    70          glutInitDisplayMode(GLUT_RGBA);
    71          glutCreateWindow("EYETEST");
    72
    73          glutTimerFunc(3000,callback_timer,0);
    74          glutDisplayFunc(callback_display);
    75
    76          glutMainLoop();
    77
    78          return 0;
    79  }
    80
takk@deb9:~$

ビルドと実行方法。math.hを使用してるので-lmも含めます。

takk@deb9:~$ gcc -lglut -lGLU -lGL -lm eyetest.c
takk@deb9:~$ ./a.out


実行すると、3秒毎に切れ目の方向が変わり、サイズも小さくなっていきます。

Leave a Reply

Your email address will not be published. Required fields are marked *

CAPTCHA