#include "myWin.h" #include "Complex.h" #include "stdio.h" #include "math.h" #define BITMX 400 #define BITMY 600 static HDC hbuf; static HBITMAP hBM; void clearBitmap(int width, int height){ SelectObject(hbuf,GetStockObject(NULL_PEN)); PatBlt(hbuf,0,0,width,height,WHITENESS); } void initBitmap(HWND hw, int width, int height){ HDC hdc=GetDC(hw); hBM=CreateCompatibleBitmap(hdc,width,height); hbuf=CreateCompatibleDC(hdc);SelectObject(hbuf,hBM); ReleaseDC(hw, hdc); } typedef struct{//表示用テーブルのための構造体 TCHAR name[10]; //関数表示用文字列 Complex(*fun)(Complex x);//実行関数アドレス double X1, Y1, X2, Y2; //独立変数の開始と終了(X:実部,Y:虚部) double SC, XST, YST; //スケールと表示基準位置 double Zmin, Zmax; //Zmin〜Mmaxの範囲で色表示(Zmin以下は黒,Zmax以上は白) double dx; //独立変数の刻み幅 }drawData; int pT=5; //Complex userF(Complex Z){return sin(1/Z);}//色々な関数を書いて確認しよう Complex userF(Complex A){return atan(tan(A));} drawData dtab[]={ {TEXT("userF(Z)"), userF, -4, -4, 4, 4, 20, 100, 150, -4, 4, 0.05 },//0 {TEXT("sin(Z)" ), sin , -4, -4, 4, 4, 20, 100, 150, -8 , 8, 0.05 },//1 {TEXT("cos(Z)" ), cos , -4, -4, 4, 4, 20, 100, 150, -8 , 8, 0.05 },//2 {TEXT("tan(Z)" ), tan , -4, -4, 4, 4, 20, 100, 150, -8 , 8, 0.05 },//3 {TEXT("exp(Z)" ), exp , -4, -4, 4, 4, 20, 100, 150, -8 , 8, 0.05 },//4 {TEXT("log(Z)" ), log , -4, -4, 4, 4, 20, 100, 150, -8 , 8, 0.05 },//5 {TEXT("sqrt(Z)"), sqrt, -4, -4, 4, 4, 20, 100, 150, 0 , 2, 0.05 },//6 {TEXT("atan(Z)"), atan, -4, -4, 4, 4, 20, 100, 150, -2 , 2, 0.02 },//7 {TEXT("asin(Z)"), asin, -4, -4, 4, 4, 20, 100, 150, -2 , 2, 0.025},//8 {TEXT("acos(Z)"), acos, -4, -4, 4, 4, 20, 100, 150, -2 , 4, 0.025},//9 {TEXT("sinh(Z)" ), sinh , -4, -4, 4, 4, 20, 100, 150, -8, 8, 0.05 },//10 {TEXT("cosh(Z)" ), cosh , -4, -4, 4, 4, 20, 100, 150, -8, 8, 0.05 },//11 {TEXT("tanh(Z)" ), tanh , -4, -4, 4, 4, 20, 100, 150, -1, 1, 0.05 },//12 {TEXT("atanh(Z)"), atanh, -4, -4, 4, 4, 20, 100, 150, -2, 2, 0.05 },//13 {TEXT("asinh(Z)"), asinh, -4, -4, 4, 4, 20, 100, 150, -2, 2, 0.05 },//14 {TEXT("acosh(Z)"), acosh, -4, -4, 4, 4, 20, 100, 150, -4, 4, 0.05 }};//15 void dspText(int X, int Y, TCHAR str[]){ HFONT hf=CreateFont(16,0,0,0,FW_NORMAL,FALSE, FALSE, FALSE, SHIFTJIS_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FIXED_PITCH|FF_MODERN, NULL); SelectObject(hbuf,hf); SetTextColor(hbuf,0); SetBkMode(hbuf,TRANSPARENT); TextOut(hbuf,X, Y ,str,lstrlen(str)); } void drawPoint(double X, double Y, COLORREF C){ SetPixel(hbuf,(int)(dtab[pT].XST + X *dtab[pT].SC+0.5), (int)(dtab[pT].YST - Y *dtab[pT].SC+0.5),C); } void drawLine(double X1, double Y1, double X2, double Y2,int width, COLORREF C){ HPEN hpen=CreatePen(PS_SOLID,width, C); SelectObject(hbuf,hpen); MoveToEx(hbuf,(int)(dtab[pT].XST + X1 *dtab[pT].SC+0.5), (int)(dtab[pT].YST - Y1 *dtab[pT].SC+0.5),NULL); LineTo(hbuf,(int)(dtab[pT].XST + X2 *dtab[pT].SC+0.5), (int)(dtab[pT].YST - Y2 *dtab[pT].SC+0.5)); DeleteObject(hpen); } void drawFrame(double X1, double Y1, double X2, double Y2){ drawLine(X1,Y1, X1,Y2,1,0); drawLine(X2,Y1,X2,Y2,1,0); drawLine(X1,Y1, X2,Y1,1,0); drawLine(X1,Y2,X2,Y2,1,0); } COLORREF setC(double Z){ if(Z>=dtab[pT].Zmax) return 0xFFFFFF; if(Z<=dtab[pT].Zmin) return 0; int CC=(int)((Z-dtab[pT].Zmin)*255/(dtab[pT].Zmax-dtab[pT].Zmin)); return RGB(CC,CC,CC); } #define RealFlag true //実数のためのグラフ描画 #define ImageFlag true //純虚数のためのグラフ描画 #define GSY 1 //グラフのためのY軸スケール void drawUnitLine(double X0, double XE, double YED){ drawLine(X0, -YED , XE, -YED ,1, 0xFF0000); drawLine(X0, GSY-YED , XE, GSY-YED ,1, 0x007700); drawLine(X0, -GSY-YED, XE, -GSY-YED,1, 0xFF0077); double XC=(X0+XE)/2; drawLine(XC, -GSY*3.2-YED, XC, GSY*3.2-YED,1, 0xFF0000); } void drawRec(){ double SDX=dtab[pT].X2-dtab[pT].X1+20/dtab[pT].SC; Complex DT, R; TCHAR str[256]; clearBitmap(BITMX,BITMY); wsprintf(str, TEXT("%s 左が結果の実部,右が結果の虚部"), dtab[pT].name); dspText(20, 20,str); for(double y=dtab[pT].Y1; y<=dtab[pT].Y2; y+=dtab[pT].dx){ DT.i=y; for(double x=dtab[pT].X1; x<=dtab[pT].X2; x+=dtab[pT].dx){ DT.r=x; R=dtab[pT].fun(DT); drawPoint(x,y,setC(R.r)); drawPoint(x+SDX,y,setC(R.i)); } } drawFrame(dtab[pT].X1 , dtab[pT].Y1, dtab[pT].X2 , dtab[pT].Y2); drawFrame(dtab[pT].X1+SDX, dtab[pT].Y1, dtab[pT].X2+SDX, dtab[pT].Y2); //---------グラフ表示----------------------------- Complex R0; double x,y,X0,Yr0, Yi0,X1,Yr1,Yi1; double YED=dtab[pT].Y2-dtab[pT].Y1,YED2=YED*2; if (RealFlag){ DT.r=dtab[pT].X1;DT.i=0; R0=dtab[pT].fun(DT);//初期値 X0=dtab[pT].X1; Yr0=R0.r; Yi0=R0.i; drawUnitLine(X0, dtab[pT].X2, YED);//-1, 0, +1 の線を描く drawUnitLine(X0+SDX, dtab[pT].X2+SDX, YED); for(x=dtab[pT].X1; x<=dtab[pT].X2; x+=dtab[pT].dx ){ DT.r=x; R=dtab[pT].fun(DT); X1=x;//関数計算とX座標設定 Yr1=R.r; if(abs(Yr1)<3.2&&abs(Yr0)<3.2) drawLine(X0, Yr0*GSY-YED, X1, Yr1*GSY-YED,2, 0xFF);//描画 Yi1=R.i; if(abs(Yi1)<3.2&& abs(Yi0)<3.2) drawLine(X0+SDX, Yi0*GSY-YED, X1+SDX, Yi1*GSY-YED,2, 0xFF); X0=X1; Yr0=Yr1;Yi0=Yi1; //次の準備 } } if(ImageFlag){ DT.r=0;DT.i=dtab[pT].Y1; R0=dtab[pT].fun(DT);//初期値 X0=dtab[pT].Y1; Yr0=R0.r;Yi0 = R0.i; drawUnitLine(X0, dtab[pT].X2, YED2);//-1, 0, +1 の線を描く drawUnitLine(X0+SDX, dtab[pT].X2+SDX, YED2); for(y=dtab[pT].Y1; y<=dtab[pT].Y2;y+=dtab[pT].dx){ DT.i=y; R=dtab[pT].fun(DT);X1=y;//関数計算とX座標設定 Yr1=R.r; if(abs(Yr1)<3.2&&abs(Yr0)<3.2) drawLine(X0, Yr0*GSY-YED2, X1, Yr1*GSY-YED2,2, 0xFF);//描画 Yi1=R.i; if(abs(Yi1)<3.2&& abs(Yi0)<3.2) drawLine(X0+SDX, Yi0*GSY-YED2, X1+SDX, Yi1*GSY-YED2,2, 0xFF); X0=X1; Yr0=Yr1;Yi0=Yi1; //次の準備 } } } void procPaint(HWND hw, WPARAM wp,LPARAM lp){ PAINTSTRUCT ps; HDC hdc=BeginPaint(hw, &ps); BitBlt(hdc,0,0,BITMX,BITMY,hbuf,0,0,SRCCOPY); EndPaint(hw,&ps); } void procLButtonDown(HWND hw, WPARAM wp,LPARAM lp){ pT++; if(pT>15) pT=0; drawRec(); InvalidateRect(hw,NULL,TRUE); } void procCreate(HWND hw, WPARAM wp,LPARAM lp){ SetWindowText(hw,TEXT("複素関数マップ(左クリックで関数の変更)")); MoveWindow(hw,0,0,BITMX,BITMY,TRUE); initBitmap(hw,BITMX,BITMY); pT=16; procLButtonDown(hw, wp,lp); } LRESULT CALLBACK WndProc(HWND hw, UINT msg, WPARAM wp,LPARAM lp){ switch(msg){ case WM_DESTROY : PostQuitMessage(0) ; return 0; case WM_CREATE : procCreate(hw,wp,lp); return 0; case WM_LBUTTONDOWN: procLButtonDown(hw,wp,lp); return 0; case WM_PAINT : procPaint(hw,wp,lp) ; return 0; } return DefWindowProc(hw,msg,wp,lp); }