浮動小数点でキューブ回転したい #2

  • (by K, 2019.11.26)

(0)

  • p20191125aに対して、少し色を変更してみました。フルカラーを使っています。

(1)

  • blaライブラリを使って描画しています。
    #include <stdio.h>
    #include <windows.h>
    #include <math.h>
    #define STATIC static
    #include "bla.c"
    
    void drawObj();
    void drawPoly(int j, int c);
    
    double vx[8], vy[8], vz[8], centerz4[6];
    int scx[8], scy[8];
    int squar[24] = { 0,4,6,2, 1,3,7,5, 0,2,3,1, 0,1,5,4, 4,5,7,6, 6,7,3,2 };
    bla_Window *win;
    
    int bla_main(int argc, const char **argv)
    {
        win = bla_openWin(256, 160, "kcube2019b", 1);
        static double vertx[8] = {  50.0,  50.0,  50.0,  50.0, -50.0, -50.0, -50.0, -50.0 };
        static double verty[8] = {  50.0,  50.0, -50.0, -50.0,  50.0,  50.0, -50.0, -50.0 };
        static double vertz[8] = {  50.0, -50.0,  50.0, -50.0,  50.0, -50.0,  50.0, -50.0 };
        int thx = 0, thy = 0, thz = 0, i, l;
        const double toRad = 3.14159265358979323 / 0x8000;
        for (;;) {
            thx = (thx + 182) & 0xffff;
            thy = (thy + 273) & 0xffff;
            thz = (thz + 364) & 0xffff;
            double xp = cos(thx * toRad), xa = sin(thx * toRad);
            double yp = cos(thy * toRad), ya = sin(thy * toRad);
            double zp = cos(thz * toRad), za = sin(thz * toRad);
            for (i = 0; i < 8; i++) {
                double xt, yt, zt;
                zt    = vertz[i] * xp + verty[i] * xa;
                yt    = verty[i] * xp - vertz[i] * xa;
                xt    = vertx[i] * yp + zt       * ya;
                vz[i] = zt       * yp - vertx[i] * ya;
                vx[i] = xt       * zp - yt *       za;
                vy[i] = yt       * zp + xt *       za;
            }
            l = 0; for (i = 0; i < 6; i++) {
                centerz4[i] = vz[squar[l + 0]] + vz[squar[l + 1]] + vz[squar[l + 2]] + vz[squar[l + 3]] + 1024.0;
                l += 4;
            }
            bla_fillRect(win, 160, 160, 40, 0, bla_rgb(0, 0, 0));
            drawObj();
            bla_flushAll(win);
            bla_waitEx(50);
        }
    }
    
    void drawObj()
    {
        int i;
        for (i = 0; i < 8; i++) {
            double t = 300.0 / (vz[i] + 400.0);
            scx[i] = (vx[i] * t) + 128;
            scy[i] = (vy[i] * t) +  80;
        }
        for (;;) {
            double max = 0.0;
            int j = -1, k;
            for (k = 0; k < 6; k++) {
                if (max < centerz4[k]) {
                    max = centerz4[k];
                    j = k;
                }
            }
            if (j < 0) break;
            i = j * 4;
            centerz4[j] = 0.0;
            double e0x = vx[squar[i + 1]] - vx[squar[i + 0]];
            double e0y = vy[squar[i + 1]] - vy[squar[i + 0]];
            double e1x = vx[squar[i + 2]] - vx[squar[i + 1]];
            double e1y = vy[squar[i + 2]] - vy[squar[i + 1]];
            if (e0x * e1y <= e0y * e1x) {
                double e0z = vz[squar[i + 1]] - vz[squar[i + 0]];
                double e1z = vz[squar[i + 2]] - vz[squar[i + 1]];
                double t = 1.0 / sqrt(e0x * e0x + e0y * e0y + e0z * e0z);
                e0x *= t; e0y *= t; e0z *= t;
                t = 1.0 / sqrt(e1x * e1x + e1y * e1y + e1z * e1z);
                e1x *= t; e1y *= t; e1z *= t;
                drawPoly(j, (int) ((e0y * e1x - e0x * e1y) * 319.9));
            }
        }
    }
    
    void drawPoly(int j, int c)
    {
        int i = j * 4, i1 = i + 3;
        int p0x = scx[squar[i1]], p0y = scy[squar[i1]], p1x, p1y;
        int y, ymin = 0x7fffffff, ymax = 0, x, dx, y0, y1;
        int *buf, buf0[160], buf1[160];
        for (i = i; i <= i1; i++) {
            p1x = scx[squar[i]];
            p1y = scy[squar[i]];
            if (ymin > p1y) ymin = p1y;
            if (ymax < p1y) ymax = p1y;
            if (p0y != p1y) {
                if (p0y < p1y) {
                    buf = buf0; y0 = p0y; y1 = p1y; dx = p1x - p0x; x = p0x;
                } else {
                    buf = buf1; y0 = p1y; y1 = p0y; dx = p0x - p1x; x = p1x;
                }
                x <<= 16;
                dx = (dx << 16) / (y1 - y0);
                if (dx >= 0)
                    x += 0x8000;
                else
                    x -= 0x8000;
                for (y = y0; y <= y1; y++) {
                    buf[y] = x >> 16;
                    x += dx;
                }
            }
            p0x = p1x;
            p0y = p1y;
        }
        if (c < 256)
            c = bla_rgb(c, c, c >> 1);
        else
            c = bla_rgb(255, 255, c - 128);
        for (y = ymin; y <= ymax; y++) {
            p0x = buf0[y];
            p1x = buf1[y];
            if (p0x <= p1x)
                bla_fillRect(win, p1x - p0x + 1, 1, p0x, y, c);
            else
                bla_fillRect(win, p0x - p1x + 1, 1, p1x, y, c);
        }
    }

こめんと欄


コメントお名前NameLink

リロード   新規 編集 差分 添付   トップ 一覧 検索 最終更新 バックアップ   ヘルプ   最終更新のRSS
Last-modified: 2019-11-26 (火) 18:56:50 (19d)