トリッキーコードネット トップへ戻る   C/C++, Java, Perl, PHP, JavaScript, アルゴリズム, ショートコーディング, IOCCCコードの解説, 等々

サイト情報

トリッキーなコード

7行プログラミング

物凄いコード集

アルゴリズム

データ構造

C/C++な話題

コードサンプル

ツール/環境構築

開発ノウハウ 等

ネタ/ジョーク集

おススメ書籍/サイト

サイトTOP >> 物凄いコード集 >> グルグル回転する球を描画 (Win32API)

回転する球 (Win32API)

#include<windows.h>
#include<math.h>
int*P,y[1<<18],a=256,c,r,m[8],n,S=a/2,u,v;BITMAPINFO T={40,a,a,1,32};HWND g;
float s,X,Y=-.57,Z,t,l,d;int WINAPI WinMain(HINSTANCE I,HINSTANCE,LPSTR,int)
{WNDCLASS w={67,DefWindowProc,0,0,I,0,0,0,0,"0"};RegisterClass(&w);HDC h=GetDC(
g=CreateWindow("0","○",513<<19,0,0,a,a,0,0,I,0));while(GetMessage((MSG*)m,g,0,0)!=-1)
{if(m[1]==15){s+=.1;Z=Y*cos(s);X=Y*sin(s);P=y;for(v=S;v>-S;v--){for(u=-S;u<S;u++)
{d=9999-u*u-v*v;d>0?t=sqrt(d),l=sqrt(u*u+v*v+t*t),n=(X*u/l+Y*v/l+Z*t/l)*255,n=n<0?0:n:
n=64;*P++=n;}}SetDIBitsToDevice(h,0,0,a,a,0,0,0,a,y,&T,0);}else DispatchMessage((MSG*)m);
InvalidateRect(g,0,0);}return 0;}
↑のコードをコンパイルして実行すると、以下の様な「グルグル回転する球」が表示されます。キタ Y⌒Y⌒Y⌒Y⌒(。A。)!!! 回転する球プログラミング (※実際にプログラムを実行すると、高速で球が回転している様子が表示されます。) よろしければ、ダウンロードして実行してみて下さい。 ⇒ code34 Win32APIのコードの為、GUIがステキでいい感じです^^;) それでは、プログラムの解説に移ります。 冒頭のコードに、適当なインデント・スペースを入れて読みやすくした物が以下のコードです。↓↓
#include<windows.h>
#include<math.h>
int *P, y[1<<18], a=256, c, r, m[8], n, S = a/2, u, v;

BITMAPINFO T = {40,a,a,1,32};
HWND g;
float s, X, Y =- .57, Z, t, l, d;

int WINAPI WinMain(HINSTANCE I, HINSTANCE, LPSTR, int)
{
    WNDCLASS w = {67, DefWindowProc, 0,0,I,0,0,0,0,"0"};

    RegisterClass(&w);

    HDC h = GetDC(
                    g = CreateWindow("0", "○", 513<<19, 0, 0, a, a, 0, 0, I, 0)
                );

    while(GetMessage((MSG*)m,g,0,0) != -1) {
        if (m[1] == 15) {
            s += .1;
            Z  = Y * cos(s);
            X  = Y * sin(s);
            P  = y;

            for (v = S; v>-S; v--) {
                for (u =- S; u<S; u++) {
                    d = 9999 - u*u - v*v;
                    d > 0 ?
                            t = sqrt(d),
                            l = sqrt(u*u+v*v+t*t),
                            n = (X*u/l+Y*v/l+Z*t/l)*255,
                            n = n < 0 ? 0 : n
                          :
                            n = 64;

                    *P++ = n;
                }
            }

            SetDIBitsToDevice(h,0,0,a,a,0,0,0,a,y,&T,0);
        }
        else
            DispatchMessage((MSG*)m);

        InvalidateRect(g,0,0);
    }

    return 0;
}
まだまだ読みにくい部分がある為、変数名を変更し、一部のコードを修正します。 そして、定義済の名称(#defineされているもの)がある値は、定義済の名称に変更します。 また、VC++2005のデフォルトのコンパイルオプションで表示される、 C4305, C4244の警告(double型からfloat型, int型からfloat型への変換警告)も、あわせて対処します。 それが以下のコードです。↓↓
 1 : #include<windows.h>
 2 : #include<math.h>
 3 :
 4 : int   c, r, n, u, v;
 5 : float s, X, Z, t, l, d;
 6 : int   *lpnBits, nBits[1<<18];
 7 :
 8 : const float Y         = -0.57f;
 9 : int nWndSize          = 256;
10 : int nHalfSize         = nWndSize/2;
11 :
12 : BITMAPINFO bitmapInfo = {sizeof(BITMAPINFOHEADER), nWndSize, nWndSize, 1, 32};
13 : HWND hWnd;
14 : MSG  msg;
15 :
16 : int WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR, int)
17 : {
18 :     WNDCLASS wndclass = {
19 :                             CS_CLASSDC | CS_VREDRAW | CS_HREDRAW,
20 :                             DefWindowProc,
21 :                             0, 0, hInst, NULL, NULL, NULL, NULL,
22 :                             "MyClass"
23 :                         };
24 :     RegisterClass(&wndclass);
25 :
26 :     hWnd    = CreateWindow(
27 :                             "MyClass", "○",
28 :                             WS_VISIBLE | WS_SYSMENU,
29 :                             0, 0, nWndSize, nWndSize,
30 :                             NULL, NULL, hInst, NULL
31 :                           );
32 :     HDC hdc = GetDC(hWnd);
33 :
34 :     while (GetMessage(&msg, hWnd, 0, 0) != -1) {
35 :         if (msg.message == WM_PAINT) {
36 :             s      += .1f;
37 :             Z       = Y * cos(s);
38 :             X       = Y * sin(s);
39 :             lpnBits = nBits;
40 :
41 :             for (v = nHalfSize; v > -nHalfSize; v--) {
42 :                 for (u =- nHalfSize; u < nHalfSize; u++) {
43 :                     d = float(9999 - u*u - v*v);
44 :                     d > 0 ?
45 :                             t = sqrt(d),
46 :                             l = sqrt(u*u+v*v+t*t),
47 :                             n = int( (X*u/l+Y*v/l+Z*t/l) * 255),
48 :                             n = n < 0 ? 0 : n
49 :                         :
50 :                         n = 64;
51 :
52 :                     *lpnBits++ = n;
53 :                 }
54 :             }
55 :
56 :             SetDIBitsToDevice(hdc, 0, 0, nWndSize, nWndSize, 0, 0,
57 :                               0, nWndSize, nBits, &bitmapInfo, 0);
58 :         }
59 :         else
60 :             DispatchMessage(&msg);
61 :
62 :         InvalidateRect(hWnd, NULL, FALSE);
63 :         Sleep(10);
64 :     }
65 :
66 :     return 0;
67 : }
【変数名の変更点】
ynBits
PlpnBits
anWndSize
SnHalfSize
ghWnd
TbitmapInfo
IhInst
wwndclass
hhdc
"0""MyClass"
【変数の型変更点】
int m[8]MSG msg
【定義済み名称への変更点】
12行目 40sizeof(BITMAPINFOHEADER)
19行目 67CS_CLASSDC | CS_VREDRAW | CS_HREDRAW
28行目 513<<19WS_VISIBLE | WS_SYSMENU
35行目 15WM_PAIN
随所FALSE または NULL
7行砂嵐プログラミングのコードを理解していれば、割と難なく読めるコードだと思います^^;) ちょっとだけ補足しておくと、 WM_PAINTメッセージの処理部分では、 nBitsにビットマップデータを保持するものとし、 lpnBitsにnBitsのアドレスを割り当て(←39行目)、 ループ内で 「 *lpnBits++ = n 」 (←52行目。ちなみに、nには計算結果が入る)をすることにより、 nBitsのビットマップデータが1つ1つ計算して埋められていきます。 そして最後に、SetDIBitsToDevice()でビットマップデータをウィンドウに描画(←56,57行目)して、球の表示処理終了!! というわけです^^;) さらに、WM_PAINTメッセージ処理で、球の描画を行う度に、変数sが「s += .1f」 (←36行目) されており、 その変数sをsin(), cos()に入れて変数Z, 変数Xの値を取得している(←37,38行目)事から、 変数Z, 変数Xへ周期的に同じ値が代入される事になり、 結果として、グルグル回転している球が表示されるというワケです^^;) いやぁ~、なかなかイキなコードだw
         このエントリーをはてなブックマークに追加   


作業効率化・ライフハックのオススメ記事




コンピュータ・テクノロジーのオススメ記事





恋愛・人間関係のオススメ記事




※ 当サイトは、トップページからリンクで辿る事の出来るページに限り、リンクフリーです。
※ 当サイトの閲覧/利用によって生じた如何なる損害も、当サイト管理人は責任を負いません。
※ 当サイトの内容を転載される場合は、当サイトへのリンクをお願い致します。