840 likes | 950 Views
9.その他のアルゴリズム 9.1 曜日を求める. ツェラー( Zeller )の公式を使うと西暦の年月日から曜日を求めることができます。 例題では,その日が日曜日であれば0,月曜日であれば1, … ,土曜日であれば6を返却する関数を示します。なお,2月の日数が一定でないので,1月・2月は前年の13月,14月とみなします。 なお,うるう年は4で割れる年ですが,100で割れるが400で割れない年は平年です。. 例題. private int WeekDay(int Y, int M, int D) // ツェラー (Zeller) の公式 {
E N D
9.その他のアルゴリズム9.1 曜日を求める9.その他のアルゴリズム9.1 曜日を求める ツェラー(Zeller)の公式を使うと西暦の年月日から曜日を求めることができます。 例題では,その日が日曜日であれば0,月曜日であれば1,…,土曜日であれば6を返却する関数を示します。なお,2月の日数が一定でないので,1月・2月は前年の13月,14月とみなします。 なお,うるう年は4で割れる年ですが,100で割れるが400で割れない年は平年です。
例題 private int WeekDay(int Y, int M, int D) // ツェラー(Zeller)の公式 { int YY=Y; int MM=M; if (M<3){YY=Y-1; MM=M+12;} return (YY +(YY/4)-(YY/100)+(YY/400)+(13*MM + 8)/5+D) % 7; } private void button1_Click(object sender, System.EventArgs e) { int Y=int.Parse(textBox1.Text); int M=int.Parse(textBox2.Text); int D=int.Parse(textBox3.Text); int R=WeekDay(Y,M,D); string X="日月火水木金土"; label4.Text = X[R]+"曜日"; }
9.2 等高線の描画 横Δx,縦Δyの長方形の各辺にhとなる点を見つけて, 線を引くと等高線を描くことができる。 Z3 Δx Z2 f(x, y)=h の 等高線 Δy h-Z1 Δy Z2-Z1 Z0 Z1 h-Z0 Δx Z1-Z0
9.2 等高線の描画 以下のような等高線の場合,点線のように描くことになるが, 格子を十分小さくとれば,実用上問題は生じない。
例題 Name : textBox1 Name : button2 フォーム定義 Name : openFileDialog1 Name : button1
実行例 数値地図読込み表示 (国土地理院発行50mメッシュ) 初期画面
例題 (以下のネームスペースを追加) using System.Drawing.Drawing2D; using System.IO;
例題 (データの宣言) private int numX=201; private int numY=201; private double dx=1.0; private double dy=1.0; private double X0, Y0; private string pbA; private double Hstep; private double[,] Z=new double[201,201]; private Matrix matrix=new Matrix(); private Image image;
例題 public double 補間(double H, double Z1, double Z2) { return ((H-Z1)/(Z2-Z1)); }
例題 public void Contour(Graphics g, int j, int k, double H){ double Z0=Z[j , k ]; double Z1=Z[j+1, k ]; double Z2=Z[j+1, k+1]; double Z3=Z[j , k+1]; bool P01 = (Z0> H) ^ (Z1 > H); bool P12 = (Z1> H) ^ (Z2 > H); bool P23 = (Z2> H) ^ (Z3 > H); bool P30 = (Z3> H) ^ (Z0 > H); if( P01 || P12 || P23 || P30){ float x0=0; float y1=0; float x2=0; float y3=0; Pen pen = new Pen(Color.Black,0.01F); if(P01) x0 =(float)( dx*(((double)j)+補間(H, Z0,Z1))); if(P12) y1 =(float)( dy*(((double)k)+補間(H, Z1,Z2))); if(P23) x2 =(float)( dx*(((double)j)+補間(H, Z3,Z2))); if(P30) y3 =(float)( dy*(((double)k)+補間(H, Z0,Z3))); float yk =(float)(dy*(double)(k )); float yk1=(float)(dy*(double)(k+1)); float xj =(float)(dx*(double)(j )); float xj1=(float)(dx*(double)(j+1)); if(P01 && P12) g.DrawLine(pen, x0 , yk , xj1, y1 ); if(P12 && P23) g.DrawLine(pen, xj1, y1 , x2 , yk1); if(P23 && P30) g.DrawLine(pen, x2 , yk1, xj , y3 ); if(P30 && P01) g.DrawLine(pen, xj , y3 , x0 , yk ); if(P01 && P23) g.DrawLine(pen, x0 , yk , x2 , yk1); if(P12 && P30) g.DrawLine(pen, xj1, y1 , xj , y3 ); } }
例題 public void Contours(Graphics g, double v1, double v2, double dv) { for(int j=0; j<numX-1; j++) for(int k=0; k<numY-1; k++) for(double v=v1; v<=v2; v +=dv) Contour(g,j,k,v); } public void ColorMap(Graphics g, double v1, double v2, double dv) { Color color; float w =(float) dx; float h =(float) dy; double DD=(v2-v1)/20; for(int j=0; j<numX-1; j++) for(int k=0; k<numY-1; k++){ float x1 =(float)( dx*((double)(j))); float y1 =(float)( dy*((double)(k))); int ID=(int)((Z[j,k]-v1)/DD); switch(ID) { case 0 : color=Color.FromArgb( 0, 63, 0); break; case 1 : color=Color.FromArgb( 0, 95, 0); break; case 2 : color=Color.FromArgb( 0,127, 0); break; case 3 : color=Color.FromArgb( 0,159, 0); break; case 4 : color=Color.FromArgb( 0,191, 0); break; case 5 : color=Color.FromArgb( 0,223, 0); break;
例題 case 6 : color=Color.FromArgb( 0,255, 0); break; case 7 : color=Color.FromArgb( 31,255, 0); break; case 8 : color=Color.FromArgb( 63,255, 0); break; case 9 : color=Color.FromArgb(127,255, 0); break; case 10 : color=Color.FromArgb(159,255, 0); break; case 11 : color=Color.FromArgb(191,255, 0); break; case 12 : color=Color.FromArgb(223,255, 0); break; case 13 : color=Color.FromArgb(255,255, 0); break; case 14 : color=Color.FromArgb(255,223, 0); break; case 15 : color=Color.FromArgb(255,191, 0); break; case 16 : color=Color.FromArgb(255,159, 0); break; case 17 : color=Color.FromArgb(255,127, 0); break; case 18 : color=Color.FromArgb(255, 63, 0); break; case 19 : color=Color.FromArgb(255, 31, 0); break; default: color=Color.FromArgb(255, 0, 0); break; } Brush brush = new SolidBrush(color); g.FillRectangle(brush,x1,y1,w,h); } }
例題 public double minZ() { double R=Z[0,0]; for(int j=0; j<numX-1; j++) for(int k=0; k<numY-1; k++) if(Z[j,k]<R) R=Z[j,k]; return R; } public double maxZ() { double R=Z[0,0]; for(int j=0; j<numX-1; j++) for(int k=0; k<numY-1; k++) if(Z[j,k]>R) R=Z[j,k]; return R; }
例題 private void 描画() { image =new Bitmap(1000,1000); Graphics g=Graphics.FromImage(image); g.Clear(this.BackColor); g.Transform=matrix; double V1=minZ(); double V2=maxZ(); if(Math.Abs(V2-V1)<0.0000001) V2=V1+1; ColorMap(g, V1, V2, 0.1); Contours(g, V1, V2, Hstep); } protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); e.Graphics.DrawImage(image,0,0); }
例題 private void window(double X1, double Y1, double X2, double Y2) { double W=this.ClientSize.Width; double H=this.ClientSize.Height; float SX=(float)(W/(X2-X1)); float SY=(float)(H/(Y2-Y1)); matrix.Scale(SX,SY); matrix.Translate(-(float)X1,-(float)Y1); } private void Form1_Load(object sender, System.EventArgs e) { double XX=((double) numX)*0.5; double YY=((double) numY)*0.5; X0 = dx * XX; Y0= dy * YY; double C = 0.02; //倍率 Hstep=double.Parse(textBox1.Text); for(int i=0; i<numX; i++) for(int j=0; j<numY; j++) { double x=C*(((double)i)-XX); double y=C*(((double)j)-YY); Z[i,j]=(x-y)*Math.Exp(-(x*x+y*y))*5000; } window(-20,240,220,-50); 描画(); }
例題 private void button1_Click(object sender, System.EventArgs e) { openFileDialog1.ShowDialog(); } private string midStr(string DT, int ist,int N) { string S="";int k=ist-1; for(int i=1 ;i<=N;i++){S = S + DT[k]; k=k+1;} return S; }
例題 private void openFileDialog1_FileOk (object sender, System.ComponentModel.CancelEventArgs e) { StreamReader DTS; int ii, pbII; string FName=openFileDialog1.FileName; if(FName == "") return; DTS=new StreamReader(FName,System.Text.Encoding.Default); pbA=DTS.ReadLine(); pbII=0;string DT=DTS.ReadLine(); while(DT !=null) { ii = 5; for(int j=0;j<200;j++) { ii = ii + 5; Z[pbII, j] = int.Parse(midStr(DT, ii, 5)); } DT=DTS.ReadLine(); pbII++; } DTS.Close(); 描画(); this.Invalidate(); }
例題 private void textBox1_TextChanged(object sender, System.EventArgs e) { Hstep=double.Parse(textBox1.Text); } private void button2_Click(object sender, System.EventArgs e) { 描画(); this.Invalidate(); }
9.3 陰線消去 等高線は,3次元形状を数値的に正確に表示するという意味では有効だが,直感的に図形を把握するのが困難 普段,見慣れた形で表示
ワイヤフレーム 3次元図形を単純に平行投影してみると, 本来は見えない部分まで表示されてしまう。 見えない部分の線を消す処理(陰線消去)を入れる
例題データ 2次元配列に以下のデータを入れて高さデータとします。
3次元データの平行投影 次のように変換します。
浮動水平線アルゴリズム ■ 一番,手前から描く。 ■ 現在描いている曲線の1点のY座標が, それ以前に描かれた曲線の最大値より大きければ, (水平線より上に位置すれば), その点が見えるものとして描く。 ■ 描画の進行に伴って, 水平線がYの正の方向に上がっていくので, 浮動水平線アルゴリズムと呼ばれる。
浮動水平線アルゴリズム 曲線が描かれていく様子 z y x 曲線を 描く順序
例題 (以下のネームスペースを追加) using System.Drawing.Drawing2D;
例題 (データ宣言) public double Hidden_dlx; // 表示刻み幅(dl) public double Hidden_alpha; // x軸と水平軸との角度(α) public double Hidden_beta; // y軸と水平軸との角度(β) public double Hidden_dx; // x軸方向の単位メッシュの長さ(dx) public double Hidden_dy; // y軸方向の単位メッシュの長さ(dy) public double[,] 高さ=new double[51,51]; // 高さ(z値) public double[] YMax=new double[2000]; // Y座標値の最大値(上の浮動水平線) public double[] YMin=new double[2000]; // Y座標値の最小値(下の浮動水平線) public double Hidden_Xlen; // 表示上のX方向長さ=(numX-1)*dx*cos(α) public double Hidden_Ylen; // 表示上のX方向長さ=(numY-1)*dx*cos(β) public int Hidden_NR; // 浮動水平線用配列の長さ public double beforX; // 現在ペン位置X public double beforY; // 現在ペン位置Y public int numX=51; // x方向メッシュ数 public int numY=51; // y方向メッシュ数 public double Hidden_dxCosA; // dx*cos(α) public double Hidden_dyCosB; // dy*cos(β) public double Hidden_dxSinA; // dx*sin(α) public double Hidden_dySinB; // dy*sin(β) public double Hidden_dlxTanA; // dl*tan(α) public double Hidden_dlxTanB; // dl*tan(β) public Matrix matrix= new Matrix(); // グローバル座標系への変換マトリックス
例題 (陰線処理) public bool Hidden_Draw(PaintEventArgs e,Pen pen,double px,double py, int p, bool Visible, bool Update) {// 陰線かどうかを判断し,陰線でない場合,線を描く。 // 関数値 : 表示後の可視フラグ // e : 描画用引数 // pen : ペン属性 // px : 補間されたX座標値(平面座標系) // py : 補間されたY座標値(平面座標系) // p : 比較する浮動水平線の位置 // Visible : 現ペン位置が見えているかどうかを示すフラグ(可視フラグ) // Update : 陰線でないとき,浮動水平線を更新するかどうかを示すフラグ if((py>=YMax[p])||(py<=YMin[p])){ if(Update && py >=YMax[p])YMax[p]=py; if(Update && py <=YMin[p])YMin[p]=py; if(Visible){ float fx1=(float)beforX; float fy1=(float)beforY; float fx2=(float)px ; float fy2=(float)py; e.Graphics.DrawLine(pen,fx1,fy1,fx2,fy2); } beforX=px;beforY=py; return true; } else{ beforX=px;beforY=py; return false; } }
例題 (OnPaintのオーバーライド(その1)) protected override void OnPaint(PaintEventArgs e ) { bool 可視フラグ=true; base.OnPaint(e); e.Graphics.Clear(Color.White); Pen pen=new Pen(Color.Black,0.02F); e.Graphics.Transform=matrix; for (int j=0;j<Hidden_NR;j++){ YMax[j]=-1E20; YMin[j]=1E20;} // 浮動水平線の初期化 double X0=80; // 表示始点位置 double Y0=100; for(int k=0;k<numY;k++) { 可視フラグ=false; for(int j=0;j<numX-1;j++){ // X軸方向描画 int p1=(int)((0.5+(Hidden_Ylen+Hidden_GroundX(j,k)) /Hidden_dlx)); int p2=(int)((0.5+(Hidden_Ylen+Hidden_GroundX(j+1,k))/Hidden_dlx)); for(int p=p1; p<=p2;p++){ // 補間 double PH=(double)(p-p1); double fp = 高さ[j,k]+(高さ[j+1,k]-高さ[j,k]) * PH * Hidden_dlx /Hidden_dxCosA; double px = PH*Hidden_dlx + Hidden_GroundX(j,k)+ X0; double py = PH*Hidden_dlxTanA + Hidden_GroundY(j,k) + fp + Y0; if((j<numX-2 && p<p2) || (j == numX-2)) 可視フラグ=Hidden_Draw(e, pen, px, py, p,可視フラグ, true); } }
例題 ( OnPaintのオーバーライド(その2)) for(int j=0;j<numX && k<numY-1;j++) { // Y軸方向描画 可視フラグ=false; int p1=(int)((0.5+(Hidden_Ylen+Hidden_GroundX(j,k)) /Hidden_dlx)); int p2=(int)((0.5+(Hidden_Ylen+Hidden_GroundX(j,k+1))/Hidden_dlx)); for(int p=p1; p>=p2;p--){ // 補間 double PH=(double)(p-p1); double fp=高さ[j,k]-(高さ[j,k+1]-高さ[j,k])*PH*Hidden_dlx /Hidden_dyCosB; double px = PH*Hidden_dlx + Hidden_GroundX(j,k) + X0; double py =-PH*Hidden_dlxTanB + Hidden_GroundY(j,k) + fp + Y0; 可視フラグ=Hidden_Draw(e, pen, px, py, p,可視フラグ, p!=p2); } } } }
例題 (初期座標値) private double Hidden_GroundX(int j, int k) // X0=Y0=0のときのX座標 { return (double)j * Hidden_dxCosA - (double) k * Hidden_dyCosB;} private double Hidden_GroundY(int j, int k) // X0=Y0=0のときのY座標 { return (double)j * Hidden_dxSinA + (double) k * Hidden_dySinB;} (変換マトリックスの設定) private void window(double X1, double Y1, double X2, double Y2) { float W=this.ClientSize.Width; float H=this.ClientSize.Height; float SX=W/((float)(X2-X1)); float SY=H/((float)(Y2-Y1)); matrix.Scale(SX,SY); matrix.Translate(-(float)X1,-(float)Y1); }
例題 (初期化) private void Form1_Load(object sender, System.EventArgs e){ double DNX2= ((double)numX)/2;double DNY2= ((double)numY)/2; // 高さデータの設定 double X,Y,R,fxy; for(int j=0; j<numX; j++){ X=0.3*((double)j-DNX2); for(int k=0; k<numY; k++){ Y=0.3*((double)k-DNY2); R=Math.Sqrt(X*X+Y*Y); if(R==0.0) fxy=1.0; else fxy=Math.Sin(R)/R; 高さ[j,k]=40.0*fxy; } } Hidden_dlx = 0.1; Hidden_alpha = Math.PI/12; // 表示用パラメータの設定 Hidden_beta = Math.PI/8; Hidden_dx = 2; Hidden_dy = 1.4; Hidden_dxCosA=Hidden_dx*Math.Cos(Hidden_alpha); // 計算に用いる値の設定 Hidden_dyCosB=Hidden_dx*Math.Cos(Hidden_beta); Hidden_dxSinA=Hidden_dx*Math.Sin(Hidden_alpha); Hidden_dySinB=Hidden_dx*Math.Sin(Hidden_beta); Hidden_Xlen=(numX-1)*Hidden_dxCosA; Hidden_Ylen=(numY-1)*Hidden_dyCosB; Hidden_dlxTanA=Hidden_dlx*Math.Tan(Hidden_alpha); Hidden_dlxTanB=Hidden_dlx*Math.Tan(Hidden_beta); Hidden_NR=(int)((Hidden_Xlen+Hidden_Ylen)/Hidden_dlx)+1; // 表示座標マトリックスの設定 window(-10,200,200,60); // 表示座標マトリックスの設定 }
9.4 ランダムドット(1)立体視とは 3次元的な物体を2次元平面上に描いて, その2次元平面の図形から元の3次元物体を 再構成してみること 2枚の絵を左右別々に見ることで 立体視ができる 左目には青が消えて見え, 右目には赤が消えて見える ので立体に見える
(2)ランダムドット・ステレオグラム 1枚の図で立体視が可能な絵 ■ 見えている物体面が紙面に対して平行であると仮定。 ■ ある基準となる面から物体面の距離をdとすると, 紙面上の間隔Tは以下の式で近似することができる。 T=C-R・d ここで, C:物体が基準となる位置にある場合に対応する 紙面上の点の間隔, R:ずらすための定数(値が大きいとき,飛び出し方や 引っ込み方が大きくなる)
ランダムドット・ステレオグラムの見方 ランダムドット・ステレオグラムの上方に,以下の(a)のような2つの点があるので, 目をリラックスさせた状態で紙面に視線を向ける。 平行法の場合は,紙面より先のほうへ,交差法の場合は,紙面より手前のほうに焦点を合わせるように見ると,これがぼやけて見える。 ぼやけた円が2個,中央にはっきりした円が1個に見えるように 目の焦点をずらすと,ステレオグラムが立体に見えてくる。 (a)最初の状態 (ぼやけてみえる) 焦点をずらす (b)立体視できる状態
例 Sin(R)/R
例 半球
例 双曲放物面
プログラム Name:comboBox1 Name:textBox1 フォーム定義
例題 (以下のネームスペースを追加) using System.Drawing.Drawing2D;
例題 (データ宣言) public Matrix matrix =new Matrix(); public string 処理; (各種関数その1) private double SinR_dev_R(double X, double Y) { double R = Math.Sqrt(X*X+Y*Y); if(R<=0.0000001) return 1.0; return Math.Sin(R)/R; } private double 半球(double X, double Y) { double R = Math.Sqrt(X*X+Y*Y); if(R>5) return -1.0; else {R=R/5; return Math.Sqrt(1-R*R)-1;} } private double 円筒(double X, double Y) { double R = Math.Abs(X); if(R>5) return -1.0; else{ R=R/5; return Math.Sqrt(1-R*R)-1;} } private double ピラミッド(double X, double Y) { double XX = Math.Abs(X); double R = Math.Abs(Y); if(XX>R) R=XX; if(R>5) return -1; else { R=R/2.5; return 1 - R; } }
例題 (各種関数その2) private double fmod(double D, double M) { return D- (int)(D/M)*M; } private double 上下開き(double X, double Y) { double R = Math.Sqrt(X*X+Y*Y); if(R>=10) return 0; else if (fmod(R, 4.0)>2.0) return Y/10; else return -Y/10; } private double 双曲放物線(double X, double Y) { return (X*X-Y*Y)/50;} private double 二次錘面(double X, double Y) { return 1- Math.Sqrt(X*X+Y*Y)/5;} private double 十字(double X, double Y) { double XX=Math.Abs(X) ; double YY=Math.Abs(Y); if (XX>5 || YY>5) return -1; else if(XX<1 || YY<1) return 1; else return -1; } private double Def_Exp(double X, double Y) { double XX=X/5 ; double YY=Y/5; double R=XX*XX+YY*YY; return (XX-YY) *Math.Exp(-R); }
例題 (各種関数その3) private double mult_R(double X, double Y) { double XX=fmod(X,4)-2 ; double YY=fmod(Y,4)-2; double R=Math.Sqrt(XX*XX+YY*YY); if (R>1) return 0; else return Math.Sqrt(1-R*R); } private double func10(double X, double Y) { return (Math.Cos(X/1.5)+Math.Sin(Y/1.5))/2;} private double func11(double X, double Y) { double XX=X/3 ; double YY=Y/3; if( XX>0) XX=-XX; if(YY>0) YY=-YY; return Math.Exp(XX+YY)*2-1; }
例題 (各種関数呼出処理) private double 関数呼出(double X, double Y) { int ID=comboBox1.SelectedIndex; switch(ID) { case 0:return SinR_dev_R(X,Y); case 1:return 半球(X,Y); case 2:return 円筒(X,Y); case 3:return ピラミッド(X,Y); case 4:return 上下開き(X,Y); case 5:return 双曲放物線(X,Y); case 6:return 二次錘面(X,Y); case 7:return 十字(X,Y); case 8:return Def_Exp(X,Y); case 9:return mult_R(X,Y); case 10:return func10(X,Y); case 11:return func11(X,Y); } return 0; }
例題 (ドットの表示) public void ドット表示(PaintEventArgs e) { double X1 = -12; double X2 = 12; double Y1 = 10; double Y2 = -10; double R0 = double.Parse(textBox1.Text); double UNIT = 6; double XY =1; int Loop=3000; double Period=(X2-X1)/6; double Z0=R0*Period; double R, X, Y, Z; Pen pen = new Pen(Color.Black,0.001F); Brush brush =new SolidBrush(Color.Black); e.Graphics.Clear(Color.White); float XX=(float)(Period/6.0);float YY=(float)(Y1*1.1); e.Graphics.DrawEllipse(pen, -XX, YY, 0.1F, 0.1F); e.Graphics.DrawEllipse(pen, XX, YY, 0.1F, 0.1F); Random RD = new Random(); for(int i=0;i<Loop;i++) { R=RD.NextDouble(); Y=R*(Y2-Y1)+Y1; Z=関数呼出(X1,Y); R=RD.NextDouble(); X=(Period + Math.Abs(Z0*Z))*R+X1; while(X<=X2) { double XP=(X - (X1+X2)*0.5)*UNIT; double YP=(Y - (Y1+Y2)*0.5)*UNIT; e.Graphics.FillRectangle(brush,(float)(X-0.025),(float)(Y-0.025),0.1F,0.1F); Z = 関数呼出(X + Period * 0.5, Y); X = X + Period - XY * Z0 * Z; } } }
例題 ( OnPaint のオーバーライド) protected override void OnPaint(PaintEventArgs e ) { base.OnPaint(e ); e.Graphics.Clear(Color.White); e.Graphics.Transform = matrix; if (処理!="")ドット表示(e); Pen pen = new Pen(Color.Black,0.001F); e.Graphics.Transform = matrix; e.Graphics.DrawLine(pen, -12F, 10F,12F, 10F); e.Graphics.DrawLine(pen, -12F,-10F,12F,-10F); e.Graphics.DrawLine(pen, -12F,10F,-12F,-10F); e.Graphics.DrawLine(pen, 12F,10F, 12F,-10F); }
例題 (関数の選択時の処理) private void comboBox1_SelectedIndexChanged(object sender, System.EventArgs e) { 処理="Exe"; this.Invalidate(); } (座標変換マトリックスの設定) private void window(float X1, float Y1, float X2, float Y2) { float W= this.Width; float H=this.Height; float SX=W/(X2-X1); float SY=H/(Y2-Y1); matrix.Scale(SX,SY); matrix.Translate(-X1,-Y1); }
例題 (初期設定) private void Form1_Load(object sender, System.EventArgs e) { 処理=""; window(-12F*1.2F, 12F*1.4F, 10F*1.4F,-10F*1.4F); comboBox1.Items.Clear(); comboBox1.Items.Add("sin(R)/R"); comboBox1.Items.Add("半球"); comboBox1.Items.Add("円筒"); comboBox1.Items.Add("ピラミッド"); comboBox1.Items.Add("上下開き"); comboBox1.Items.Add("双曲放物面"); comboBox1.Items.Add("二次錘面"); comboBox1.Items.Add("十字"); comboBox1.Items.Add("(x-y)exp(-(x*x+y*y))"); comboBox1.Items.Add("繰返し"); comboBox1.Items.Add("cos(x)+sin(y)"); comboBox1.Items.Add("exp(-(abs(x)+abs(y))"); comboBox1.SelectedIndex=0; }
9.5 スプライン曲線とベジェ曲線 GraphicsクラスのDrawCurveメソッドや DrawBezierメソッドを使うとスプライン曲線や,ベジェ曲線を描くことができます。
9.5 スプライン曲線とベジェ曲線 スプライン曲線では,閉曲線も描くことができます。 さらにメソッドにテンションを引数で受け渡すことで,歪曲度を変更することができます。
9.5 スプライン曲線とベジェ曲線 以下の例は,テンションを連続的に変化させ,テンションの値によって線の色を変えたものです。