Option Explicit On Option Strict On Public Class Form1 Private Structure SAKUZU Dim sxjiku As String 'x軸名 Dim syjiku As String 'y軸名 Dim kxi0 As Integer 'x軸最小値(px) Dim kxf0 As Integer 'x軸最大値(px) Dim kyi0 As Integer 'y軸最小値(px) Dim kyf0 As Integer 'y軸最大値(px) Dim xmin As Double 'x軸最小値 Dim xmax As Double 'x軸最大値 Dim dx As Double 'x軸増分 Dim ymin As Double 'y軸最小値 Dim ymax As Double 'y軸最大値 Dim dy As Double 'y軸増分 End Structure Private Sub ToolStripButton1_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ToolStripButton1.Click Call main() MessageBox.Show("処理完了", "完了通知") End Sub Private Sub main() Dim i As Integer Dim dt As Double Dim ndata As Integer Dim nn As Integer Dim fname1 As String = "" Dim sr As System.IO.StreamReader Dim dat As String Dim sbuf() As String Dim delim() As Char = {","c} Dim xr() As Double Dim xi() As Double Dim fq() As Double Dim fs() As Double Dim ddy() As Double Dim dy() As Double Dim y() As Double Dim ddymax As Double Dim dymax As Double Dim ymax As Double 'データ入力 OpenFileDialog1.InitialDirectory = My.Computer.FileSystem.CurrentDirectory If OpenFileDialog1.ShowDialog() = Windows.Forms.DialogResult.OK Then fname1 = OpenFileDialog1.FileName sr = New System.IO.StreamReader(fname1, System.Text.Encoding.Default) dat = sr.ReadLine() : sbuf = dat.Split(delim) dat = sr.ReadLine() : sbuf = dat.Split(delim) : dt = CDbl(sbuf(1)) dat = sr.ReadLine() : sbuf = dat.Split(delim) : ndata = CInt(sbuf(1)) 'FFT用データ数決定 nn = 2 Do nn = nn * 2 Loop While nn < ndata ReDim ddy(nn - 1) ReDim dy(nn - 1) ReDim y(nn - 1) ReDim xr(nn - 1) ReDim xi(nn - 1) ReDim fq(CInt(nn / 2)) ReDim fs(CInt(nn / 2)) For i = 1 To nn 'データ数を2の階乗にセット ddy(i - 1) = 0.0 : dy(i - 1) = 0.0 : y(i - 1) = 0.0 Next For i = 1 To ndata dat = sr.ReadLine() : sbuf = dat.Split(delim) : ddy(i - 1) = CDbl(sbuf(0)) Next i sr.Close() 'フーリエスペクトル算出 Call IACC(ndata, dt, ddy, dy, y, ddymax, dymax, ymax) '数値積分 Call CRAC(ndata, dt, ddy, dy, y, ddymax, dymax, ymax) '基線補正 For i = 1 To nn xr(i - 1) = ddy(i - 1) xi(i - 1) = 0.0 Next i Call FFT(nn, xr, xi) 'フーリエ変換 For i = 1 To nn '戻り値をデータ数で除す xr(i - 1) = xr(i - 1) / CDbl(nn) xi(i - 1) = xi(i - 1) / CDbl(nn) Next i For i = 1 To CInt(nn / 2) + 1 fq(i - 1) = CDbl(i - 1) / CDbl(nn) / dt '振動数 fs(i - 1) = dt * CDbl(nn) * Math.Sqrt(xr(i - 1) * xr(i - 1) + xi(i - 1) * xi(i - 1)) 'フーリエスペクトル Next i '平滑化処理と作図 Dim fname2 As String = "" Dim jj As Integer Dim kpt As Integer Dim HSIZE As Integer = 1000 Dim DHL As Integer = 100 Dim DHR As Integer = 20 Dim VSIZE As Integer = 400 Dim DVL As Integer = 60 Dim DVU As Integer = 60 Dim nd As Integer Dim datax() As Double Dim datay() As Double Dim fsmax As Double Dim df As Double Dim band As Double Dim g As Graphics Dim bmp As Bitmap Dim pltdata As SAKUZU nd = CInt(nn / 2) ReDim datax(nd) ReDim datay(nd) pltdata.sxjiku = "振動数 (Hz)" pltdata.syjiku = "フーリエスペクトル" pltdata.kxi0 = DHL pltdata.kxf0 = HSIZE - DHR pltdata.kyi0 = DVU pltdata.kyf0 = VSIZE - DVL pltdata.xmin = 0.0 : pltdata.xmax = 10.0 : pltdata.dx = 1.0 pltdata.ymin = 0.0 : pltdata.ymax = 1.0 : pltdata.dy = 0.1 df = 1.0 / dt / CDbl(nn) kpt = 2 For jj = 0 To 3 Select Case jj Case 0 : band = 0.0 : fname2 = "out0.png" Case 1 : band = 0.4 : fname2 = "out1.png" Case 2 : band = 0.6 : fname2 = "out2.png" Case 3 : band = 1.0 : fname2 = "out3.png" End Select For i = 0 To nd datax(i) = fq(i) : datay(i) = fs(i) Next i Call SWIN(nn, datay, df, band) 'スペクトル平滑化 fsmax = datay(0) For i = 0 To nd '最大値検索 If fsmax <= datay(i) Then fsmax = datay(i) Next i For i = 0 To nd datay(i) = datay(i) / fsmax Next i PictureBox1.Size = New Size(kpt * HSIZE, kpt * VSIZE) PictureBox1.Visible = False bmp = New Bitmap(PictureBox1.Width, PictureBox1.Height) PictureBox1.Image = bmp g = Graphics.FromImage(PictureBox1.Image) g.FillRectangle(Brushes.White, 0, 0, PictureBox1.Width, PictureBox1.Height) Call PLOT(g, kpt, pltdata, nd, datax, datay, "N", "N", band, fsmax) fname2 = System.IO.Path.GetDirectoryName(fname1) & "\" & fname2 PictureBox1.Image.Save(fname2, System.Drawing.Imaging.ImageFormat.Png) g.Dispose() Next jj End Sub Private Sub FFT(ByVal nn As Integer, ByRef xr() As Double, ByRef xi() As Double) Dim g As Integer : Dim h As Integer : Dim i As Integer : Dim j As Integer : Dim k As Integer Dim l As Integer : Dim m As Integer : Dim n As Integer : Dim p As Integer : Dim q As Integer Dim a As Double : Dim b As Double : Dim xd As Double Dim s() As Double Dim c() As Double n = nn ReDim s(n) ReDim c(n) i = 0 : j = 0 : k = 0 : l = 0 : p = 0 : h = 0 : g = 0 : q = 0 m = CInt(System.Math.Log(CDbl(n)) / System.Math.Log(2.0) + 1.0) a = 0.0 : b = Math.PI * 2.0 / CDbl(n) For i = 0 To CInt(n / 2) s(i) = System.Math.Sin(a) : c(i) = System.Math.Cos(a) : a = a + b Next i l = n : h = 1 For g = 1 To m l = CInt(l / 2) : k = 0 For q = 1 To h p = 0 For i = k To l + k - 1 j = i + l a = xr(i) - xr(j) : b = xi(i) - xi(j) xr(i) = xr(i) + xr(j) : xi(i) = xi(i) + xi(j) If p = 0 Then xr(j) = a : xi(j) = b Else xr(j) = a * c(p) + b * s(p) : xi(j) = b * c(p) - a * s(p) End If p = p + h Next i k = k + l + l Next q h = h + h Next g j = CInt(n / 2) For i = 1 To n - 1 k = n If j < i Then xd = xr(i) : xr(i) = xr(j) : xr(j) = xd xd = xi(i) : xi(i) = xi(j) : xi(j) = xd End If k = CInt(k / 2) Do While j >= k j = j - k : k = CInt(k / 2) If k = 0 Then Exit Do Loop j = j + k Next i End Sub Private Sub IACC(ByVal nn As Integer, ByVal dt As Double, ByRef ddy() As Double, ByRef dy() As Double, ByRef y() As Double, _ ByRef ddymax As Double, ByRef dymax As Double, ByRef ymax As Double) '加速度時刻歴数値積分 'nn:加速度時刻歴データ総数 'dt :時間間隔(入力値) 'ddy() :加速度時刻歴(入力値) 'dy() :速度時刻歴(計算出力) 'y() :変位時刻歴(計算出力値) 'ddymax:加速度最大値(計算出力値) 'dymax :速度最大値(計算出力値) 'ymax :変位最大値(計算出力値) Dim i As Integer ddymax = 0.0 dymax = 0.0 ymax = 0.0 dy(0) = 0.0 y(0) = 0.0 For i = 1 To nn - 1 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 < System.Math.Abs(ddy(i))) Then ddymax = System.Math.Abs(ddy(i)) If (dymax < System.Math.Abs(dy(i))) Then dymax = System.Math.Abs(dy(i)) If (ymax < System.Math.Abs(y(i))) Then ymax = System.Math.Abs(y(i)) Next i End Sub Private Sub CRAC(ByVal nn As Integer, ByVal dt As Double, ByRef ddy() As Double, ByRef dy() As Double, ByRef y() As Double, _ ByVal ddymax As Double, ByVal dymax As Double, ByVal ymax As Double) '加速度時刻歴基線補正 'nn:加速度時刻歴データ総数 'dt :時間間隔(入力値) 'ddy() :加速度時刻歴(入力値・書換出力値) 'dy() :速度時刻歴(入力値) 'y() :変位時刻歴(入力値) 'ddymax:加速度最大値(入力値) 'dymax :速度最大値(入力値) 'ymax :変位最大値(入力値) Dim i As Integer Dim tt As Double Dim t As Double Dim sum As Double Dim a1 As Double Dim a0 As Double Dim acmax As Double Dim coef As Double tt = CDbl(nn - 1) * dt t = 0.0 For i = 0 To nn - 1 y(i) = y(i) * (3.0 * tt - 2.0 * t) * t * t t = t + dt Next i sum = (y(0) + y(nn - 1)) / 2.0 For i = 1 To nn - 2 sum = sum + y(i) Next i sum = sum * dt a1 = 28.0 / 13.0 / tt / tt * (2.0 * dy(nn - 1) - 15.0 / System.Math.Pow(tt, 5.0) * sum) a0 = dy(nn - 1) / tt - a1 / 2.0 * tt t = 0.0 acmax = 0.0 For i = 0 To nn - 1 ddy(i) = ddy(i) - a0 - a1 * t If (acmax < System.Math.Abs(ddy(i))) Then acmax = System.Math.Abs(ddy(i)) t = t + dt Next i coef = ddymax / acmax For i = 0 To nn - 1 ddy(i) = ddy(i) * coef Next i End Sub Private Sub SWIN(ByVal nn As Integer, ByRef fs() As Double, ByVal df As Double, ByVal band As Double) 'スペクトル平滑化 'nn :時刻歴全数 'fs() :フーリエ・スペクトル 'df :スペクトルの振動数間隔(Hz) 'band :バンド幅(Hz) 'nfold:スペクトル値総数 Dim w() As Double Dim g() As Double Dim g1() As Double Dim g2() As Double Dim tt As Double Dim udf As Double Dim dif As Double Dim s As Double Dim i As Integer Dim j As Integer Dim nfold As Integer Dim lmax As Integer Dim ll As Integer Dim ln As Integer Dim lt As Integer Dim le As Integer Dim pi As Double ReDim g(nn - 1) ReDim g1(nn - 1) ReDim g2(nn - 1) pi = Math.PI nfold = CInt(nn / 2) + 1 If band > 0.0 Then tt = 1.0 / df udf = 280.0 / 151.0 / band * df lmax = CInt(2.0 / udf) + 1 ReDim w(lmax - 1) If udf <= 0.5 Then w(0) = 0.75 * udf For i = 2 To lmax dif = 0.5 * pi * CDbl(i - 1) * udf w(i - 1) = w(0) * System.Math.Pow(System.Math.Sin(dif) / dif, 4.0) Next i g(0) = fs(0) * fs(0) / tt For i = 2 To nfold - 1 g(i - 1) = 2.0 * fs(i - 1) * fs(i - 1) / tt Next i g(nfold - 1) = fs(nfold - 1) * fs(nfold - 1) / tt ll = lmax * 2 - 1 ln = ll - 1 + nfold lt = (ll - 1) * 2 + nfold le = lt - lmax + 1 For i = 1 To lt g1(i - 1) = 0.0 Next i For i = 1 To nfold g1(ll - 2 + i) = g(i - 1) Next i For i = lmax To le s = w(0) * g1(i - 1) For j = 2 To lmax s = s + w(j - 1) * (g1(i - j) + g1(i + j - 2)) Next j g2(i - 1) = s Next i For j = 2 To lmax g2(ll + j - 2) = g2(ll + j - 2) + g2(ll - j) g2(ln - j) = g2(ln - j) + g2(ln + j - 2) Next j For i = 1 To nfold g(i - 1) = g2(ll - 2 + i) Next i fs(0) = System.Math.Sqrt(g(0) * tt) For i = 2 To nfold - 1 fs(i - 1) = System.Math.Sqrt(g(i - 1) * tt / 2.0) Next i fs(nfold - 1) = System.Math.Sqrt(g(nfold - 1) * tt) End If End If End Sub Private Sub PLOT(ByVal g As Graphics, ByVal kpt As Integer, ByVal pltdata As SAKUZU, _ ByVal nd As Integer, ByRef datax() As Double, ByRef datay() As Double, _ ByVal slogx As String, ByVal slogy As String, ByVal band As Double, ByVal fsmax As Double) Dim i As Integer Dim j As Integer Dim kxi As Integer : Dim kxf As Integer Dim kyi As Integer : Dim kyf As Integer Dim xx As Double : Dim yy As Double Dim kxx As Integer : Dim kyy As Integer Dim kxx1 As Integer : Dim kyy1 As Integer Dim kxx2 As Integer : Dim kyy2 As Integer Dim str As String Dim f As New Font("MS ゴシック", kpt * 16, FontStyle.Bold) Dim TextSize1 As New System.Drawing.SizeF Dim TextSize2 As New System.Drawing.SizeF kxi = kpt * pltdata.kxi0 kxf = kpt * pltdata.kxf0 kyi = kpt * pltdata.kyi0 kyf = kpt * pltdata.kyf0 '座標軸 Dim LPen As New System.Drawing.Pen(System.Drawing.Color.Black) LPen.DashStyle = Drawing2D.DashStyle.Dot If slogx = "N" Then Call DRN_XJIKU(g, f, LPen, kpt, pltdata.xmin, pltdata.xmax, pltdata.dx, kxi, kxf, kyi, kyf) If slogy = "N" Then Call DRN_YJIKU(g, f, LPen, kpt, pltdata.ymin, pltdata.ymax, pltdata.dy, kxi, kxf, kyi, kyf) If slogx = "L" Then Call DRL_XJIKU(g, f, LPen, kpt, pltdata.xmin, pltdata.xmax, kxi, kxf, kyi, kyf) If slogy = "L" Then Call DRL_YJIKU(g, f, LPen, kpt, pltdata.ymin, pltdata.ymax, 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 = CInt(kxi - kpt * 10 - TextSize1.Width - TextSize2.Height) kyy = CInt((kyi + kyf) / 2 + TextSize2.Width / 2) Call INC_STR(g, f, str, kxx, kyy, -90) 'x軸名描画 str = pltdata.sxjiku TextSize2 = g.MeasureString(str, f) kxx = CInt((kxi + kxf) / 2 - TextSize2.Width / 2) kyy = CInt(kyf + kpt * 10 + TextSize1.Height) Call INC_STR(g, f, str, kxx, kyy, 0) 'データを線で連結 xx = datax(0) yy = datay(0) kxx1 = kxi + CInt((xx - pltdata.xmin) * (kxf - kxi) / (pltdata.xmax - pltdata.xmin)) kyy1 = kyf - CInt((yy - pltdata.ymin) * (kyf - kyi) / (pltdata.ymax - pltdata.ymin)) For i = 1 To nd xx = datax(i) yy = datay(i) If xx < pltdata.xmin Then xx = pltdata.xmin If pltdata.xmax < xx Then xx = pltdata.xmax If yy < pltdata.ymin Then yy = pltdata.ymin If pltdata.ymax < yy Then yy = pltdata.ymax kxx2 = kxi + CInt((xx - pltdata.xmin) * (kxf - kxi) / (pltdata.xmax - pltdata.xmin)) kyy2 = kyf - CInt((yy - pltdata.ymin) * (kyf - kyi) / (pltdata.ymax - pltdata.ymin)) g.DrawLine(New Pen(Color.Blue, 2), kxx1, kyy1, kxx2, kyy2) kxx1 = kxx2 kyy1 = kyy2 Next i Dim nfp As Integer Dim kfp() As Integer ReDim kfp(nd - 1) '極大値となる周波数 j = -1 For i = 1 To nd - 1 If (datay(i - 1) < datay(i)) And (datay(i) > datay(i + 1)) Then '極大値となる番号の検索 j = j + 1 : kfp(j) = i End If Next i nfp = j If 0.0001 < band Then f = New Font("MS ゴシック", kpt * 12, FontStyle.Italic) For j = 0 To nfp xx = datax(kfp(j)) yy = datay(kfp(j)) If pltdata.xmax < xx Then Exit For kxx = kxi + CInt((xx - pltdata.xmin) * (kxf - kxi) / (pltdata.xmax - pltdata.xmin)) kyy = kyf - CInt((yy - pltdata.ymin) * (kyf - kyi) / (pltdata.ymax - pltdata.ymin)) str = xx.ToString("0.000") TextSize2 = g.MeasureString(str, f) kxx = kxx - CInt(TextSize2.Height / 2) kyy = kyy - 1 * kpt Call INC_STR(g, f, str, kxx, kyy, -90) Next j End If f = New Font("MS ゴシック", kpt * 16, FontStyle.Bold) str = "バンド幅:" & band.ToString("0.0") & " Hz" If band < 0.0001 Then str = "原波形" TextSize2 = g.MeasureString(str, f) g.DrawString(str, f, Brushes.Black, kxf - TextSize2.Width - 5 * kpt, kyi + 5 * kpt) str = "max:" & fsmax.ToString("0") & "(gal*sec)" TextSize2 = g.MeasureString(str, f) g.DrawString(str, f, Brushes.Black, kxf - TextSize2.Width - 5 * kpt, kyi - 25 * kpt) f.Dispose() End Sub Private Sub INC_STR(ByVal g As Graphics, ByVal f As System.Drawing.Font, ByVal str As String, _ ByVal kxx As Integer, ByVal kyy As Integer, ByVal ang As Single) '軸名描画 g.ScaleTransform(1.0, 1.0) '横・縦の表示比率を設定 g.TranslateTransform(kxx, kyy) '表示位置の設定(表示位置を原点とする座標移動) g.RotateTransform(ang) '表示角度を指定 g.DrawString(str, f, Brushes.Black, 0, 0) '描画実行 g.ResetTransform() '単位行列にリセット End Sub Private Sub DRN_XJIKU(ByVal g As Graphics, ByVal f As System.Drawing.Font, ByVal LPen As System.Drawing.Pen, _ ByVal kpt As Integer, _ ByVal xmin As Double, ByVal xmax As Double, ByVal dx As Double, _ ByVal kxi As Integer, ByVal kxf As Integer, _ ByVal kyi As Integer, ByVal kyf As Integer) Dim i As Integer Dim ix As Integer Dim xx As Double Dim wv As Double Dim str As String Dim kxx As Integer Dim TextSize1 As New System.Drawing.SizeF '普通x軸描画 ix = CInt((xmax - xmin) / dx) For i = 0 To ix xx = xmin + CDbl(i) * dx kxx = kxi + CInt((xx - xmin) * (kxf - kxi) / (xmax - xmin)) wv = xmin + CDbl(i) * dx str = wv.ToString("0") If CInt(dx * 1000.0) Mod 10 <> 0 Then str = wv.ToString("0.000") If CInt(dx * 1000.0) Mod 10 = 0 And CInt(dx * 100.0) Mod 10 <> 0 Then str = wv.ToString("0.00") If (CInt(dx * 1000.0) Mod 10 = 0 And CInt(dx * 100.0) Mod 10 = 0) And CInt(dx * 10.0) Mod 10 <> 0 Then 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 + kpt * 3) Next i End Sub Private Sub DRN_YJIKU(ByVal g As Graphics, ByVal f As System.Drawing.Font, ByVal LPen As System.Drawing.Pen, _ ByVal kpt As Integer, _ ByVal ymin As Double, ByVal ymax As Double, ByVal dy As Double, _ ByVal kxi As Integer, ByVal kxf As Integer, _ ByVal kyi As Integer, ByVal kyf As Integer) Dim i As Integer Dim iy As Integer Dim yy As Double Dim wv As Double Dim str As String Dim kyy As Integer Dim TextSize1 As New System.Drawing.SizeF '普通y軸描画 iy = CInt((ymax - ymin) / dy) For i = 0 To iy yy = ymin + CDbl(i) * dy kyy = kyf - CInt((yy - ymin) * (kyf - kyi) / (ymax - ymin)) wv = ymin + CDbl(i) * dy str = wv.ToString("0") If CInt(dy * 1000.0) Mod 10 <> 0 Then str = wv.ToString("0.000") If CInt(dy * 1000.0) Mod 10 = 0 And CInt(dy * 100.0) Mod 10 <> 0 Then str = wv.ToString("0.00") If (CInt(dy * 1000.0) Mod 10 = 0 And CInt(dy * 100.0) Mod 10 = 0) And CInt(dy * 10.0) Mod 10 <> 0 Then 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 - kpt * 2, kyy - TextSize1.Height / 2) Next i End Sub Private Sub DRL_XJIKU(ByVal g As Graphics, ByVal f As System.Drawing.Font, ByVal LPen As System.Drawing.Pen, _ ByVal kpt As Integer, _ ByVal xmin As Double, ByVal xmax As Double, _ ByVal kxi As Integer, ByVal kxf As Integer, _ ByVal kyi As Integer, ByVal kyf As Integer) Dim i As Integer Dim j As Integer Dim xx As Double Dim str As String Dim kxx As Integer Dim TextSize1 As New System.Drawing.SizeF '対数x軸描画 For i = CInt(xmin) To CInt(xmax) - 1 For j = 1 To 9 xx = System.Math.Log(CDbl(j) * System.Math.Pow(10.0, CDbl(i))) / System.Math.Log(10.0) kxx = kxi + CInt((xx - xmin) * (kxf - kxi) / (xmax - xmin)) g.DrawLine(LPen, kxx, kyi, kxx, kyf) Next j Next i For i = CInt(xmin) To CInt(xmax) xx = CDbl(i) kxx = kxi + CInt((xx - xmin) * (kxf - kxi) / (xmax - xmin)) str = CStr(System.Math.Pow(10.0, CDbl(i))) TextSize1 = g.MeasureString(str, f) g.DrawString(str, f, Brushes.Black, kxx - TextSize1.Width / 2, kyf + kpt * 3) Next i End Sub Private Sub DRL_YJIKU(ByVal g As Graphics, ByVal f As System.Drawing.Font, ByVal LPen As System.Drawing.Pen, _ ByVal kpt As Integer, _ ByVal ymin As Double, ByVal ymax As Double, _ ByVal kxi As Integer, ByVal kxf As Integer, _ ByVal kyi As Integer, ByVal kyf As Integer) Dim i As Integer Dim j As Integer Dim yy As Double Dim str As String Dim kyy As Integer Dim TextSize1 As New System.Drawing.SizeF '対数y軸描画 For i = CInt(ymin) To CInt(ymax) - 1 For j = 1 To 9 yy = System.Math.Log(CDbl(j) * System.Math.Pow(10.0, CDbl(i))) / System.Math.Log(10.0) kyy = kyf - CInt((yy - ymin) * (kyf - kyi) / (ymax - ymin)) g.DrawLine(LPen, kxi, kyy, kxf, kyy) Next j Next i For i = CInt(ymin) To CInt(ymax) yy = CDbl(i) kyy = kyf - CInt((yy - ymin) * (kyf - kyi) / (ymax - ymin)) str = CStr(System.Math.Pow(10.0, CDbl(i))) TextSize1 = g.MeasureString(str, f) g.DrawString(str, f, Brushes.Black, kxi - TextSize1.Width - kpt * 2, kyy - TextSize1.Height / 2) Next i End Sub End Class