next up previous contents index
: シミュレーション : 数値積分法 : レイアウト   目次   索引

プログラムの実装手順

開始点,終了点,分割数を読んで,Simpson公式を用いて積分を求めるためのプログラムを次のように書く。

=======================================================
void CSimpsonDlg::OnCalc()
{
//開始点$ a$,終了点$ b$,分割数$ n$を読み込む。
UpdateData(TRUE);
double a = m_Inputa;
double b = m_Inputb;
int n = m_Inputn;
//区間幅 $ h = (b-a)/n$を決める。
double h = (b-a)/n;
// $ sum1 = f(x_{2}) + f(x_{4}) + \cdots + f(x_{n})$を関数 $ F(x)=\sqrt{16 - x^{2}}$を用いて求める。
double sum1=0;
for(int i = 1; i $ <$ n/2; i++){
x = a + 2*i*h;
sum1 = sum1 + F(x);
}
// $ sum2 = f(x_{1}) + f(x_{3}) + \cdots + f(x_{n-1})$を関数 $ F(x)=\sqrt{16 - x^{2}}$を用いて求める。
double sum2=0;
double x2;
for(int j = 1; j $ <$= n/2; j++){
x = a + (2*j-1)*h;
sum2 = sum2 + F(x);
}

//和を台形公式より求める。
double s; s = (h/3)* (F(a) + F(b) + 2*sum1 + 4*sum2);
m_Output.Format("%2.6lf",s);
UpdateData(FALSE);
}
=======================================================

ユーザ関数の追加 数学関数を用いるので,ヘッダファイルの追加が必要である。C++では,数学関数は$ <$cmath$ >$に含まれている。そこで,ヘッダファイルの追加を行う必要がある。

#include <cmath>

=======================================================
dobule CSimpsonDlg::F(double x)
{
return sqrt(16 - x*x);
}
=======================================================
これで,積分をするプログラムは完成。

クリッピング領域

ピクチャー コントロールをはみ出して、描画命令を実行するような場合には、外側の部分を切り落とす必要がある。つまりクリッピング 領域 (region)を設定しなければならない。クリッピング領域は使い終わったら、削除しなければならない。

// (x1, y1) が左上の頂点の座標
// (x2, y2) が右上の頂点の座標
// x1, y1, x2, y2 はすべて整数値
CRgn s;
s.CreateRectRgn(x1, y1, x2, y2);
pDC-$ >$SelectClipRgn(&s);
// クリッピング領域の削除
s.DeleteObject();

次に描画を行う。

void CSimpsonDlg::OnDraw()
{
CWnd$ \ast$ h = GetDlgItem(IDC_PICTURE);
CDC$ \ast$ pDC=h-$ >$GetDC();
CRect r; // 長方形データを格納する場所を設定
h-$ >$GetClientRect(&r); // クライアント領域を r に格納
int pw,ph;
pw=r.right;
ph=r.bottom;
//1目盛りの値をdx,dyとする.
double dx = pw/20.0, dy = ph/20.0;
//目盛線をシアンで描く
CPen p(PS_SOLID,1,RGB(0,255,255));
CPen* oldp=pDC-$ >$SelectObject(&p);
//縦の目盛線群を描く
for(double x=0;x$ <$=pw;x+=dx){
pDC-$ >$MoveTo(int(x),0);
pDC-$ >$LineTo(int(x),ph);
}
//横の目盛線群を描く
for(double y=0; y$ <$=ph; y+=dy){
pDC-$ >$MoveTo(0,int(y));
pDC-$ >$LineTo(pw,int(y));
}
// ペンを戻す
pDC-$ >$SelectObject(oldp);
//グラフを赤で描く。クリッピング領域を長方形の大きさに設定する。
CRgn s;
s.CreateRectRgn(0,0,pw,ph);
pDC->SelectClipRgn(&s);
int xg,yg; for(x=-4;x$ <$=4;x+=0.01){
y = F(x);
xg = xc + int(dx*x);
yg = yc - int(dy*y);
pDC-$ >$SetPixel(int(xg),int(yg),RGB(255,0,0));
}
//領域の塗りつぶし
double a = m_Inputa;
double b = m_Inputb;
for(x=a;x$ <$=b;x+=0.01){
double y=F(x);
xg = cx + int(dx*x);
yg = cy - int(dy*y);
pDC-$ >$MoveTo(xg,yg);
pDC-$ >$LineTo(xg,cy);
}
s.DeleteObject();
h-$ >$ReleaseDC(pDC);
}
=======================================================


next up previous contents index
: シミュレーション : 数値積分法 : レイアウト   目次   索引
Administrator 平成16年7月8日