2007年7月27日金曜日

円柱のHSV色空間


最近文字列ばかりだったので、一息入れる意味で3D。

奥行きの計算は厳密なものではなく近似したものです。

#include "d3m.hsp"
#include "hspda.as"

#const H_MAX      12
#const S_MAX      4
#const V_MAX      7
#const PANEL_MAX  H_MAX * S_MAX * V_MAX
#const PANEL_SIZE 150                   // パネル一辺の長さ
#const PANEL_DIST 200                   // 同じ角度上のパネル同士の距離(左下の座標の間)
#const OBSERVER_R 2000                  // 観測者の中心からの距離

#const double PI        3.1415
#const double ANG_SPEED 0.04            // 観測者の角速度

    ct = 0.0
    d3setcam OBSERVER_R, 0, V_MAX * 100,  00, V_MAX * 100

*init
    dim  panel_h,   PANEL_MAX : dim  panel_s,   PANEL_MAX : dim  panel_v,   PANEL_MAX  // 色(HSV指定)
    dim  panel_r,   PANEL_MAX : ddim panel_t,   PANEL_MAX : dim  panel_z,   PANEL_MAX  // パネルの位置 円柱座標系(パネルの左下の座標)
    ddim panel_far, PANEL_MAX   // 奥行き

    repeat H_MAX : cnt1 = cnt
        h = 191 * cnt / H_MAX                       // HSV の H
        t = PI * 2.0 * cnt / H_MAX                  // 角度
        repeat S_MAX : cnt2 = cnt
            s = 256 * cnt / S_MAX                   // HSV の S
            r = cnt * PANEL_DIST + PANEL_DIST / 2   // 中心からの距離
            repeat V_MAX
                v = 256 * cnt / V_MAX               // HSV の V

                i = cnt1 * S_MAX * V_MAX + cnt2 * V_MAX + cnt
                panel_h( i ) = h : panel_s( i ) = s : panel_v( i ) = v
                panel_r( i ) = r : panel_t( i ) = t : panel_z( i ) = cnt * PANEL_DIST
            loop
        loop
    loop
    observer_t = 0.0

*main
    gosub *calc
    gosub *draw
    wait 2
    goto *main

*calc
    // 観測者の回転
    observer_t += ANG_SPEED
    if ( PI * 2.0 < observer_t ) : observer_t -= PI * 2.0
    d3setlocal 0,0,0cos( observer_t ),sin( observer_t ),0, -sin( observer_t ),cos( observer_t ),00,0,1

    // 奥行きを計算。遠くにあるものほどpanel_farは小さくなる
    repeat PANEL_MAX
        panel_far( cnt ) = cos( panel_t( cnt ) - observer_t ) * panel_r( cnt )
    loop
    // 小さい順(昇順)に並べ替え
    sortval panel_far, 0
    return

*draw
    redraw 0
    hsvcolor 00, ( sin( observer_t )  + 1.0 ) * 128 : boxf
    repeat PANEL_MAX
        sortget i, cnt // 奥から数えてcnt番目のパネルのインデックス
        x = cos( panel_t( i ) ) * panel_r( i ), cos( panel_t( i ) ) * ( panel_r( i ) + PANEL_SIZE ), cos( panel_t( i ) ) * ( panel_r( i ) + PANEL_SIZE ), cos( panel_t( i ) ) * panel_r( i )
        y = sin( panel_t( i ) ) * panel_r( i ), sin( panel_t( i ) ) * ( panel_r( i ) + PANEL_SIZE ), sin( panel_t( i ) ) * ( panel_r( i ) + PANEL_SIZE ), sin( panel_t( i ) ) * panel_r( i )
        z = panel_z( i ) + PANEL_SIZE, panel_z( i ) + PANEL_SIZE, panel_z( i ), panel_z( i )
        hsvcolor panel_h( i ), panel_s( i ), panel_v( i )
        d3square x, y, z
    loop
    redraw 1
    return

0 件のコメント: