using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace vcsEQSP { struct DRAWPARA { public int kpt; //拡大率(画面表示:1,ファイル保存:2) public int HSIZE; //画像横寸法(px) public int DHL; //画像左余白寸法:縦軸描画用(px) public int DHR; //画像右余白寸法(px) public int VSIZE; //画像縦寸法(px) public int DVL; //画像下余白寸法:横軸描画用(px) public int DVU; //画像上余白寸法(px) public string sxjiku; //x軸名(単位含む) public double xmin; //x軸最小値 public double xmax; //x軸最大値 public double dx; //x軸増分 public string slogx; //x軸の種類(L:対数,N:普通) public string syjiku; //y軸名(単位含む) public double ymin; //y軸最小値 public double ymax; //y軸最大値 public double dy; //y軸増分 public string slogy; //y軸の種類(L:対数,N:普通) public int kxi0; //グラフ左端座標 public int kxf0; //グラフ右端座標 public int kyi0; //グラフ上端座標 public int kyf0; //グラフ下端座標 } public partial class Form1 : Form { const double pi = Math.PI; public Form1() { InitializeComponent(); } private void toolStripButton1_Click(object sender, EventArgs e) { main_part(); } //--------------------------------------------------------------------------- private void main_part() { System.IO.StreamReader sr; System.IO.StreamWriter sw; string fnameR = ""; string fnameW = ""; string dat; string[] sbuf; char delim = ','; int i; string scom; //コメント double dt; //サンプリングピッチ(sec) int nn; //サンプリングデータ数 double h = 0.05; //減衰定数 int nt = 200; //周期計算個数 double[] tk = new double[nt]; //計算周期 double[] resacc = new double[nt]; //加速度応答 double[] resvel = new double[nt]; //速度応答 double[] resdis = new double[nt]; //変位応答 double[] datax = new double[nt]; //出力用配列 double[] datay = new double[nt]; //出力用配列 double ddymax, dymax, ymax; //入出力ファイル指定 openFileDialog1.InitialDirectory = System.IO.Directory.GetCurrentDirectory(); if (openFileDialog1.ShowDialog() == DialogResult.OK) fnameR = openFileDialog1.FileName; if (saveFileDialog1.ShowDialog() == DialogResult.OK) fnameW = saveFileDialog1.FileName; //データ入力 sr = new System.IO.StreamReader(fnameR, System.Text.Encoding.Default); dat = sr.ReadLine(); scom = dat; dat = sr.ReadLine(); sbuf = dat.Split(delim); dt = double.Parse(sbuf[1]); dat = sr.ReadLine(); sbuf = dat.Split(delim); nn = int.Parse(sbuf[1]); double[] ddy = new double[nn]; //加速度時刻歴 double[] dy = new double[nn]; //速度時刻歴 double[] y = new double[nn]; //変位時刻歴 for (i=0;i<= nn-1;i++){ dat = sr.ReadLine(); sbuf = dat.Split(delim); ddy[i] = double.Parse(sbuf[0]); } sr.Close(); //計算周期(sec)設定 for(i=0;i<=nt-1;i++){ tk[i]=Math.Pow(10.0, Math.Log10(2.0 * dt)+(Math.Log10(10.0)-Math.Log10(2.0 * dt))/(double)nt*(double)i); } //応答スペクトル計算 IACC(nn, dt, ddy, dy, y, out ddymax, out dymax, out ymax); //加速度時刻歴数値積分 CRAC(nn, dt, ddy, dy, y, ddymax, dymax, ymax); //加速度時刻歴基線補正 ERES(nn, dt, h, ddy, nt, tk, resacc, resvel, resdis); //応答スペクトル計算 for(i=0;i<=nt-1;i++){ datax[i] = tk[i]; datay[i] = resacc[i]; } //データ書き込み saveFileDialog1.Filter = "*.csv|*.csv|*.txt|*.txt"; sw = new System.IO.StreamWriter(fnameW, false, System.Text.Encoding.Default); sw.WriteLine(scom); sw.WriteLine("ndata,"+nt.ToString("0")); sw.WriteLine("period(sec),acc(gal),vel(kine),dis(cm)"); for(i=0;i<=nt-1;i++){ sw.WriteLine(tk[i].ToString("0.00000") + "," + resacc[i].ToString("0.000") + "," + resvel[i].ToString("0.000") + "," + resdis[i].ToString("0.000")); } sw.Close(); //作図 DRAWPARA pltdata; DEC_PLTDATA(out pltdata); PLTCTL(pltdata,nt - 1, datax, datay,scom); } //--------------------------------------------------------------------------- private void ERES(int nn, double dt, double h, double[] ddy, int nt, double[] tk, double[] resacc, double[] resvel, double[] resdis) { //応答値算出 //nn :加速度時刻歴総数 //dt :時間間隔(入力値) //h :減衰定数(入力値) //ddy[] :加速度時刻歴(入力値) //nt :計算周期総数[データ格納0〜nt-1](入力値) //tk[] :計算周期(入力値) //resacc[]:加速度応答スペクトル(計算値) //resvel[]:速度応答スペクトル(計算値) //resdis[]:変位応答スペクトル(計算値) int i, m; double accmax, velmax, dismax;//応答最大値(gal,kine,cm) double w, w2, hw, wd, wdt, e, cwdt, swdt; double ss, cc, s1, c1, s2, c2, s3, c3; double A11, A12, A21, A22, B11, B12, B21, B22; double dxf, xf, ddym, ddyf, x, dx, ddx; for (i = 0; i <= nt - 1; i++) { w = 2.0 * pi / tk[i]; w2 = w * w; hw = h * w; wd = w * Math.Sqrt(1.0 - h * h); wdt = wd * dt; e = Math.Exp(-hw * dt); cwdt = Math.Cos(wdt); swdt = Math.Sin(wdt); A11 = e * (cwdt + hw * swdt / wd); A12 = e * swdt / wd; A21 = -e * w2 * swdt / wd; A22 = e * (cwdt - hw * swdt / wd); ss = -hw * swdt - wd * cwdt; cc = -hw * cwdt + wd * swdt; s1 = (e * ss + wd) / w2; c1 = (e * cc + hw) / w2; s2 = (e * dt * ss + hw * s1 + wd * c1) / w2; c2 = (e * dt * cc + hw * c1 - wd * s1) / w2; s3 = dt * s1 - s2; c3 = dt * c1 - c2; B11 = -s2 / wdt; B12 = -s3 / wdt; B21 = (hw * s2 - wd * c2) / wdt; B22 = (hw * s3 - wd * c3) / wdt; accmax = 2.0 * hw * Math.Abs(ddy[0]) * dt; velmax = Math.Abs(ddy[0]) * dt; dismax = 0.0; dxf = -ddy[0] * dt; xf = 0.0; for (m = 1; m <= nn - 1; m++) { ddym = ddy[m]; ddyf = ddy[m - 1]; x = A12 * dxf + A11 * xf + B12 * ddym + B11 * ddyf; dx = A22 * dxf + A21 * xf + B22 * ddym + B21 * ddyf; ddx = -2.0 * hw * dx - w2 * x; if (accmax <= Math.Abs(ddx)) accmax = Math.Abs(ddx); if (velmax <= Math.Abs(dx)) velmax = Math.Abs(dx); if (dismax <= Math.Abs(x)) dismax = Math.Abs(x); dxf = dx; xf = x; } resacc[i] = accmax; resvel[i] = velmax; resdis[i] = dismax; } } //--------------------------------------------------------------------------- private void IACC(int nn, double dt, double[] ddy, double[] dy, double[] y, out double ddymax, out double dymax, out double ymax) { //加速度時刻歴数値積分 //nn:加速度時刻歴データ総数 //dt :時間間隔(入力値) //ddy[] :加速度時刻歴(入力値) //dy[] :速度時刻歴(計算出力) //y[] :変位時刻歴(計算出力値) //ddymax:加速度最大値(計算出力値) //dymax :速度最大値(計算出力値) //ymax :変位最大値(計算出力値) int i; ddymax = 0.0; dymax = 0.0; ymax = 0.0; dy[0] = 0.0; y[0] = 0.0; for (i = 1; i <= nn - 1; i++) { dy[i] = dy[i - 1] + (ddy[i - 1] + ddy[i]) * dt / 2.0; y[i] = y[i - 1] + dy[i - 1] * dt + (ddy[i - 1] / 3.0 + ddy[i] / 6.0) * dt * dt; if (ddymax< Math.Abs(ddy[i]))ddymax = Math.Abs(ddy[i]); if (dymax< Math.Abs(dy[i]))dymax = Math.Abs(dy[i]); if (ymax< Math.Abs(y[i]))ymax = Math.Abs(y[i]); } } //--------------------------------------------------------------------------- private void CRAC(int nn, double dt, double[] ddy, double[] dy, double[] y, double ddymax, double dymax, double ymax) { //加速度時刻歴基線補正 //nn:加速度時刻歴データ総数 //dt :時間間隔(入力値) //ddy[] :加速度時刻歴(入力値・書換出力値) //dy[] :速度時刻歴(入力値) //y[] :変位時刻歴(入力値) //ddymax:加速度最大値(入力値) //dymax :速度最大値(入力値) //ymax :変位最大値(入力値) int i; double tt, t, sum, a1, a0, acmax, coef; tt = (double)(nn - 1) * dt; t = 0.0; for (i = 0; i <= nn - 1; i++) { y[i] = y[i] * (3.0 * tt - 2.0 * t) * t * t; t = t + dt; } sum = (y[0] + y[nn - 1]) / 2.0; for (i = 1; i <= nn - 2; i++) { sum = sum + y[i]; } sum = sum * dt; a1 = 28.0 / 13.0 / tt / tt * (2.0 * dy[nn - 1] - 15.0 / Math.Pow(tt, 5.0) * sum); a0 = dy[nn - 1] / tt - a1 / 2.0 * tt; t = 0.0; acmax = 0.0; for (i = 0; i <= nn - 1; i++) { ddy[i] = ddy[i] - a0 - a1 * t; if (acmax < Math.Abs(ddy[i])) acmax = Math.Abs(ddy[i]); t = t + dt; } coef = ddymax / acmax; for (i = 0; i <= nn - 1; i++) { ddy[i] = ddy[i] * coef; } } //--------------------------------------------------------------------------- private void PLTCTL(DRAWPARA pltdata,int nd,double[] datax,double[] datay,string scom) { //nd:データ数(入力はデータ数,プログラム上数値はデータ数−1) //datax[]:プロットデータx座標 //datay[]:プロットデータy座標 int i; PictureBox thePicBox = pictureBox1; Bitmap bmp; Graphics g; //データ対数値処理 if (pltdata.slogx == "L") { for (i = 0; i <= nd; i++) { if (datax[i] < Math.Pow(10.0, pltdata.xmin)) { datax[i] = Math.Pow(10.0, pltdata.xmin); } datax[i] = Math.Log10(datax[i]); } } if (pltdata.slogy == "L") { for (i = 0; i <= nd; i++) { if (datay[i] < Math.Pow(10.0, pltdata.ymin)) { datay[i] = Math.Pow(10.0, pltdata.ymin); } datay[i] = Math.Log10(datay[i]); } } for (i = 0; i <= 1; i++) { switch (i) { case 0: //画面描画} pltdata.kpt = 1; thePicBox = pictureBox1; thePicBox.Visible = true; break; case 1: //画像書き出し pltdata.kpt = 2; thePicBox = pictureBox2; thePicBox.Visible = false; break; } thePicBox.Size = new Size(pltdata.kpt * pltdata.HSIZE, pltdata.kpt * pltdata.VSIZE); bmp = new Bitmap(thePicBox.Width, thePicBox.Height); thePicBox.Image = bmp; g = Graphics.FromImage(thePicBox.Image); g.FillRectangle(Brushes.White, 0, 0, thePicBox.Width, thePicBox.Height); PLOT(g, pltdata, nd, datax, datay, scom); g.Dispose(); } pictureBox1.Left = 0; pictureBox1.Top = toolStrip1.Height; this.ClientSize = new Size(pictureBox1.Width, pictureBox1.Height + toolStrip1.Height); } //--------------------------------------------------------------------------------- private void PLOT(Graphics g, DRAWPARA pltdata,int nd, double[] datax, double[] datay,string scom) { int i; int kxi, kxf, kyi, kyf; double xx, yy; int kxx, kyy; int kxx1, kyy1, kxx2, kyy2; string str; System.Drawing.Font f = new Font("MSゴシック", pltdata.kpt * 10); System.Drawing.SizeF TextSize1; System.Drawing.SizeF TextSize2; kxi = pltdata.kpt * pltdata.kxi0; kxf = pltdata.kpt * pltdata.kxf0; kyi = pltdata.kpt * pltdata.kyi0; kyf = pltdata.kpt * pltdata.kyf0; //座標軸 System.Drawing.Pen LPen = new Pen(System.Drawing.Color.Black); LPen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot; if (pltdata.slogx == "N") { DRN_XJIKU(g, f, LPen, pltdata, kxi, kxf, kyi, kyf); } if (pltdata.slogy == "N") { DRN_YJIKU(g, f, LPen, pltdata, kxi, kxf, kyi, kyf); } if (pltdata.slogx == "L") { DRL_XJIKU(g, f, LPen, pltdata, kxi, kxf, kyi, kyf); } if (pltdata.slogy == "L") { DRL_YJIKU(g, f, LPen, pltdata, kxi, kxf, kyi, kyf); } //枠線描画 g.DrawRectangle(new Pen(Color.Black, 2), kxi, kyi, kxf - kxi, kyf - kyi); //y軸名描画 str = pltdata.syjiku; TextSize2 = g.MeasureString(str, f); TextSize1 = g.MeasureString("-1.0", f); kxx = (int)(kxi - pltdata.kpt * 10 - TextSize1.Width - TextSize2.Height); kyy = (int)((kyi + kyf) / 2 + TextSize2.Width / 2); INC_STR(g, f, str, kxx, kyy, -90); //x軸名描画 str = pltdata.sxjiku; TextSize2 = g.MeasureString(str, f); kxx = (int)((kxi + kxf) / 2 - TextSize2.Width / 2); kyy = (int)(kyf + pltdata.kpt * 5 + TextSize1.Height); INC_STR(g, f, str, kxx, kyy, 0); //データプロット //int dc; //dc = pltdata.kpt * 5; //for (i = 0; i <= nd; i++) //{ // xx = datax[i]; // yy = datay[i]; // kxx = kxi + (int)((xx - pltdata.xmin) * (kxf - kxi) / (pltdata.xmax - pltdata.xmin)) - (int)(dc / 2); // kyy = kyf - (int)((yy - pltdata.ymin) * (kyf - kyi) / (pltdata.ymax - pltdata.ymin)) - (int)(dc / 2); // g.DrawEllipse(new Pen(Color.Red, 1), kxx, kyy, dc, dc); //} //データを線で連結 xx = datax[0]; yy = datay[0]; kxx1 = kxi + (int)((xx - pltdata.xmin) * (kxf - kxi) / (pltdata.xmax - pltdata.xmin)); kyy1 = kyf - (int)((yy - pltdata.ymin) * (kyf - kyi) / (pltdata.ymax - pltdata.ymin)); for (i = 1; i <= nd; i++) { xx = datax[i]; yy = datay[i]; kxx2 = kxi + (int)((xx - pltdata.xmin) * (kxf - kxi) / (pltdata.xmax - pltdata.xmin)); kyy2 = kyf - (int)((yy - pltdata.ymin) * (kyf - kyi) / (pltdata.ymax - pltdata.ymin)); g.DrawLine(new Pen(Color.Blue, 2), kxx1, kyy1, kxx2, kyy2); kxx1 = kxx2; kyy1 = kyy2; } //右上コメント str = scom; TextSize1 = g.MeasureString(str, f); kxx = kxf - 2 * pltdata.kpt - (int)TextSize1.Width; kyy = kyi - 2 * pltdata.kpt - (int)TextSize1.Height; g.DrawString(str, f, Brushes.Black, kxx,kyy); f.Dispose(); } //--------------------------------------------------------------------------------- private void INC_STR(Graphics g, System.Drawing.Font f, string str, int kxx, int kyy, float ang) { //軸名描画 g.ScaleTransform(1, 1);//横・縦の表示比率を設定 g.TranslateTransform(kxx, kyy);//表示位置の設定(表示位置を原点とする座標移動) g.RotateTransform(ang);//表示角度を指定 g.DrawString(str, f, Brushes.Black, 0, 0);//描画実行 g.ResetTransform();//単位行列にリセット } //--------------------------------------------------------------------------------- private void DRN_XJIKU(Graphics g, System.Drawing.Font f, System.Drawing.Pen LPen, DRAWPARA pltdata, int kxi, int kxf, int kyi, int kyf) { int i, ix, kxx; double xx, wv; string str; System.Drawing.SizeF TextSize1; //普通x軸描画 ix = (int)((pltdata.xmax - pltdata.xmin) / pltdata.dx); for (i = 0; i <= ix; i++) { xx = pltdata.xmin + (double)(i) * pltdata.dx; kxx = kxi + (int)((xx - pltdata.xmin) * (kxf - kxi) / (pltdata.xmax - pltdata.xmin)); wv = pltdata.xmin + (double)(i) * pltdata.dx; str = wv.ToString("0"); if ((int)(pltdata.dx * 1000.0) % 10 != 0) { str = wv.ToString("0.000"); } if ((int)(pltdata.dx * 1000.0) % 10 == 0 && (int)(pltdata.dx * 100.0) % 10 != 0) { str = wv.ToString("0.00"); } if ((int)(pltdata.dx * 1000.0) % 10 == 0 && (int)(pltdata.dx * 100.0) % 10 == 0 && (int)(pltdata.dx * 10.0) % 10 != 0) { str = wv.ToString("0.0"); } TextSize1 = g.MeasureString(str, f); g.DrawLine(LPen, kxx, kyi, kxx, kyf); g.DrawString(str, f, Brushes.Black, kxx - TextSize1.Width / 2, kyf + pltdata.kpt * 3); } } //--------------------------------------------------------------------------------- private void DRN_YJIKU(Graphics g, System.Drawing.Font f, System.Drawing.Pen LPen, DRAWPARA pltdata, int kxi, int kxf, int kyi, int kyf) { int i, iy, kyy; double yy, wv; string str; System.Drawing.SizeF TextSize1; //普通y軸描画 iy = (int)((pltdata.ymax - pltdata.ymin) / pltdata.dy); for (i = 0; i <= iy; i++) { yy = pltdata.ymin + (double)(i) * pltdata.dy; kyy = kyf - (int)((yy - pltdata.ymin) * (kyf - kyi) / (pltdata.ymax - pltdata.ymin)); wv = pltdata.ymin + (int)(i) * pltdata.dy; str = wv.ToString("0"); if ((int)(pltdata.dy * 1000.0) % 10 != 0) { str = wv.ToString("0.000"); } if ((int)(pltdata.dy * 1000.0) % 10 == 0 && (int)(pltdata.dy * 100.0) % 10 != 0) { str = wv.ToString("0.00"); } if ((int)(pltdata.dy * 1000.0) % 10 == 0 && (int)(pltdata.dy * 100.0) % 10 == 0 && (int)(pltdata.dy * 10.0) % 10 != 0) { str = wv.ToString("0.0"); } TextSize1 = g.MeasureString(str, f); g.DrawLine(LPen, kxi, kyy, kxf, kyy); g.DrawString(str, f, Brushes.Black, kxi - TextSize1.Width - pltdata.kpt * 2, kyy - TextSize1.Height / 2); } } //--------------------------------------------------------------------------------- private void DRL_XJIKU(Graphics g, System.Drawing.Font f, System.Drawing.Pen LPen, DRAWPARA pltdata, int kxi, int kxf, int kyi, int kyf) { int i, j, kxx; double xx; string str; System.Drawing.SizeF TextSize1; //対数x軸描画 for (i = (int)pltdata.xmin; i <= (int)pltdata.xmax - 1; i++) { for (j = 1; j <= 9; j++) { xx = Math.Log10((double)(j) * Math.Pow(10.0, (double)i)); kxx = kxi + (int)((xx - pltdata.xmin) * (kxf - kxi) / (pltdata.xmax - pltdata.xmin)); g.DrawLine(LPen, kxx, kyi, kxx, kyf); } } for (i = (int)pltdata.xmin; i <= (int)pltdata.xmax; i++) { xx = (double)i; kxx = kxi + (int)((xx - pltdata.xmin) * (kxf - kxi) / (pltdata.xmax - pltdata.xmin)); str = Math.Pow(10.0, (double)i).ToString(); TextSize1 = g.MeasureString(str, f); g.DrawString(str, f, Brushes.Black, kxx - TextSize1.Width / 2, kyf + pltdata.kpt * 3); } } //--------------------------------------------------------------------------------- private void DRL_YJIKU(Graphics g, System.Drawing.Font f, System.Drawing.Pen LPen, DRAWPARA pltdata, int kxi, int kxf, int kyi, int kyf) { int i, j; double yy; string str; int kyy; System.Drawing.SizeF TextSize1; //対数y軸描画 for (i = (int)pltdata.ymin; i <= (int)pltdata.ymax - 1; i++) { for (j = 1; j <= 9; j++) { yy = Math.Log10((double)j * Math.Pow(10.0, (double)i)); kyy = kyf - (int)((yy - pltdata.ymin) * (kyf - kyi) / (pltdata.ymax - pltdata.ymin)); g.DrawLine(LPen, kxi, kyy, kxf, kyy); } } for (i = (int)pltdata.ymin; i <= (int)pltdata.ymax; i++) { yy = (double)i; kyy = kyf - (int)((yy - pltdata.ymin) * (kyf - kyi) / (pltdata.ymax - pltdata.ymin)); str = (Math.Pow(10.0, (double)i)).ToString(); TextSize1 = g.MeasureString(str, f); g.DrawString(str, f, Brushes.Black, kxi - TextSize1.Width - pltdata.kpt * 2, kyy - TextSize1.Height / 2); } } //--------------------------------------------------------------------------------- private void DEC_PLTDATA(out DRAWPARA pltdata) { pltdata.kpt=1; //拡大率(画面表示:1,ファイル保存:2) pltdata.HSIZE=600; //画像横寸法(px) pltdata.DHL=70; //画像左余白寸法:縦軸描画用(px) pltdata.DHR=20; //画像右余白寸法(px) pltdata.VSIZE=300; //画像縦寸法(px) pltdata.DVL=40; //画像下余白寸法:横軸描画用(px) pltdata.DVU=20; //画像上余白寸法(px) pltdata.sxjiku="周期(sec)"; //x軸名(単位含む) pltdata.xmin=-2.0; //x軸最小値 pltdata.xmax=1.0; //x軸最大値 pltdata.dx=1.0; //x軸増分 pltdata.slogx="L"; //x軸の種類(L:対数,N:普通) pltdata.syjiku="加速度応答スペクトル(gal)"; //y軸名(単位含む) pltdata.ymin=1.0; //y軸最小値 pltdata.ymax=4.0; //y軸最大値 pltdata.dy=1.0; //y軸増分 pltdata.slogy="L"; //y軸の種類(L:対数,N:普通) //プロット領域定義 pltdata.kxi0 = pltdata.DHL; pltdata.kxf0 = pltdata.HSIZE - pltdata.DHR; pltdata.kyi0 = pltdata.DVU; pltdata.kyf0 = pltdata.VSIZE - pltdata.DVL; } //--------------------------------------------------------------------------------- private void toolStripButton2_Click_1(object sender, EventArgs e) { string fname2 = ""; saveFileDialog1.Filter = "*.bmp|*.bmp|*.jpg|*.jpg|*.png|*.png|*.wmf|*.wmf|*.tif|*.tif|*.gif|*.gif"; if (saveFileDialog1.ShowDialog() == DialogResult.OK) { fname2 = saveFileDialog1.FileName; } switch (saveFileDialog1.FilterIndex) { case 1: pictureBox2.Image.Save(fname2, System.Drawing.Imaging.ImageFormat.Bmp); break; case 2: pictureBox2.Image.Save(fname2, System.Drawing.Imaging.ImageFormat.Jpeg); break; case 3: pictureBox2.Image.Save(fname2, System.Drawing.Imaging.ImageFormat.Png); break; case 4: pictureBox2.Image.Save(fname2, System.Drawing.Imaging.ImageFormat.Wmf); break; case 5: pictureBox2.Image.Save(fname2, System.Drawing.Imaging.ImageFormat.Tiff); break; case 6: pictureBox2.Image.Save(fname2, System.Drawing.Imaging.ImageFormat.Gif); break; } } //--------------------------------------------------------------------------------- } }