'============================================================== ' ' Functional BlackBoard for Win10 R 2025 :Form4 for graphics ' ' Ver0.011 Copy Right Miyama. ' ' http://kazutomimiyama.sakura.ne.jp ' KazutomiMiyamaSub@gmail.com ' '============================================================== ' このフォームの論理はForm1が作成した複 '合関数を参照して自前の画像オブジェクトに 'グラフを表示。 Option Explicit On Imports System Imports System.IO Imports System.Math '数学ライブラリ Public Class Form4 '<グローバルオブジェクトの宣言> '描画用変数 Public g 'As Graphics 'グラフィックオブジェクト Public p As Object 'penオブジェクトのプロパティ '例 pens.black を格納 Dim VacantCHR As String = "" Dim PeriodCHR As String = "." Dim CummaCHR As String = "," Dim FW, FH As Integer 'フォームサイズ Dim JustBeforeWidth As Double '描画用の一段階前のフォームオブジェクト? Dim JustBeforeHeight As Double 'これらの変数は使っていない Dim FSO As Object = CreateObject("scripting.filesystemobject") Dim WTS As StreamWriter 'For Configuration Dim RTS As StreamReader Dim RedBack As String Dim GreenBack As String Dim BlueBack As String Dim PensColor As String Dim CNFGFileName As String = "GraphicCNFG.txt" Dim FormWidCNFGSTRwithEq As String = "FormWidth=" Dim BackColorCNFGSTRwithEq As String = "BackColor=" Dim PensColorCNFGSTRwithEq As String = "PensColor=" '参照のためこれらはみんなgrobal Dim Xa As Double Dim Xb As Double Dim Ya As Double Dim Yb As Double Dim DeltaXSmallSegmant As Double '計算用補助変数いわゆるΔx Dim Y(10 ^ 5) As Double '計算結果の格納配列十万確保、動的配列にはしなかった。 Dim TotalNumOfDeltaX As Double 'Δxの総数、十万のうち一部使用。 '============================================================== 'フォームロードとそれに付随する初期化 '============================================================== Public Sub FormCompRelocation() Dim SBR As Double = 0.085 'FW FH = FW * (12 - 1) / 12 With Me .Width = FW .Height = FH End With 'Small Box base Rate 'RelocSUB(comp, sbr, sbr, sbr, sbr) Me.Text = "FunctionalBlackBoard R 2025" ' w h L t RelocSUB(GraPic, 0.8, 0.8, 0, 0) 'グラフィックオブジェクト RelocSUB(LineColorCMB, SBR * 2, SBR, SBR, 0.8) '色彩選択コンボボックス RelocSUB(BackColorCMB, SBR * 2, SBR, SBR, 0.85) RelocSUB(ExitBTN, SBR * 2, SBR, 0.8, SBR * 0) ExitBTN.Text = "Exit &X" RelocSUB(CalcStepTXT, SBR, SBR, 0.8, SBR * 1) RelocSUB(PictureCLRBTN, SBR, SBR, 0.8 + SBR, SBR * 1) RelocSUB(MinXTXT, SBR * 2, SBR / 2, 0.8, SBR * 2) MinXTXT.BackColor = Color.FromArgb(230, 243, 255) RelocSUB(MaxXTXT, SBR * 2, SBR / 2, 0.8, SBR * 2.5) MaxXTXT.BackColor = Color.FromArgb(196, 226, 255) RelocSUB(MinYTXT, SBR * 2, SBR / 2, 0.8, SBR * 3) With MinYTXT .BackColor = Color.FromArgb(255, 234, 220) End With RelocSUB(MaxYTXT, SBR * 2, SBR / 2, 0.8, SBR * 3.5) With MaxYTXT .BackColor = Color.FromArgb(240, 220, 200) End With RelocSUB(CalcBTN, SBR, SBR, 0.8, SBR * 4) RelocSUB(ExpressionBTN, SBR, SBR, 0.8 + SBR, SBR * 4) RelocSUB(LineColorCMB, SBR * 2, SBR / 2, 0.8, SBR * 5) RelocSUB(BackColorCMB, SBR * 2, SBR / 2, 0.8, SBR * 5.5) RelocSUB(dot1000CHK, SBR * 2, SBR / 2, 0.8, SBR * 6) dot1000CHK.Checked = True RelocSUB(CalcoutTXT, SBR * 2, SBR * 2.9, 0.8, SBR * 6.5) 'tabindex----- MinXTXT.TabIndex = 0 MaxXTXT.TabIndex = 1 MinYTXT.TabIndex = 2 MinYTXT.TabIndex = 3 CalcBTN.TabIndex = 4 ExpressionBTN.TabIndex = 5 LineColorCMB.TabIndex = 6 BackColorCMB.TabIndex = 7 PictureCLRBTN.TabIndex = 8 CalcStepTXT.TabIndex = 9 ExitBTN.TabIndex = 10 CalcoutTXT.TabIndex = 11 End Sub Public Sub RelocSUB(cont As Control, W_Rate As Double, H_Rate As Double, L_Rate As Double, T_Rate As Double) 'コントロールの配置 Dim PicTune As Integer = FW / 12 With cont .Visible = True .Width = FW * W_Rate .Height = (FH + PicTune) * H_Rate .Left = FW * L_Rate .Top = (FH + PicTune) * T_Rate End With End Sub Public Sub PicRefresh() 'グラフィックスオブジェクトの初期化 '画面を消去する毎に必要な処理 g.Dispose() GraPic.Refresh() g = GraPic.CreateGraphics End Sub Public Sub Form_load() '読み込み時に若干の初期化を行う FW = 600 RedBack = "064" GreenBack = "064" BlueBack = "128" PensColor = "Yellow" FormCompRelocation() ReflectBackColor() ReflectPensColor() ''minmaxTXTinit() Call ReadCNFG() With LineColorCMB 'ペンは濃い色でいい。 .Items.Add("white") .Items.Add("BlueBack") .Items.Add("green") .Items.Add("red") .Items.Add("yellow") .Items.Add("purple") .Items.Add("water") .Items.Add("black") End With With BackColorCMB '背景は薄い色をたくさん用意 .Items.Add("white") '色彩名は公称名ではない .Items.Add("lampblack") .Items.Add("paintgray") .Items.Add("shoolboard") .Items.Add("billiardgreen") .Items.Add("brawn") .Items.Add("brilliantgreen") .Items.Add("waterBlueBack") .Items.Add("brilliantwater") .Items.Add("BlueBackpurple") .Items.Add("indigo") .Items.Add("redpurple") .Items.Add("magenta") .Items.Add("softred") .Items.Add("salmonpink") .Items.Add("softyellow") .Items.Add("lemon") '.items.Add("white") '以下濃すぎてペンが目立たなくなる '.items.Add("BlueBack") 'またどぎつくて疲れる。2 '.items.Add("green") '.items.Add("red") '.items.Add("yellow") '.items.Add("purple") '.items.Add("water") '.items.Add("Black") End With g = GraPic.CreateGraphics '初めてdisposeする前には宣言しなくてはならない PicRefresh() Call minmaxTXTinit() '+-1範囲の初期化を代入 Call TotalNumOfDeltaXinit() '>計算・描画範囲の変数を初期化する論理を呼び出す。 End Sub Public Sub Form_click(sender As Object, e As EventArgs) Handles Me.Click FW = Me.Width FormCompRelocation() WriteCNFG() End Sub Public Sub CalcStepTXT_LostFocus(sendar As Object, e As EventArgs) Handles CalcStepTXT.LostFocus '計算間隔の取得と反映 TotalNumOfDeltaXinit() '他でも使いたいのでモジュール化 End Sub Public Sub TotalNumOfDeltaXinit() 'アクセスするためにモジュール化 Dim tmpValue As Double = 1000 With CalcStepTXT tmpValue = Val(.Text) If tmpValue <= 0 Or 10 ^ 5 < tmpValue Then tmpValue = 1000 End If TotalNumOfDeltaX = tmpValue .Text = CStr(tmpValue) End With End Sub Public Sub dot1000CHK_checkedchanged(sender As Object, e As EventArgs) Handles dot1000CHK.CheckedChanged If dot1000CHK.Checked = True Then CalcStepTXT.Text = "1000" End If TotalNumOfDeltaXinit() End Sub Public Sub ReadCNFG() Dim ReadSTR As String Dim tmpARR(2 - 1) As String Dim colorarr(3 - 1) As String If FSO.fileexists(CNFGFileName) = True Then RTS = New StreamReader(CNFGFileName) With RTS While .EndOfStream = False ReadSTR = .ReadLine If 0 < InStr(ReadSTR, FormWidCNFGSTRwithEq) Then tmpARR = Split(ReadSTR, "=") FW = Val(tmpARR(1)) FormCompRelocation() Else If 0 < InStr(ReadSTR, BackColorCNFGSTRwithEq) Then tmpARR = Split(ReadSTR, "=") colorarr = Split(tmpARR(1), CummaCHR) RedBack = colorarr(0) GreenBack = colorarr(1) BlueBack = colorarr(2) ReflectBackColor() Else If 0 < InStr(ReadSTR, PensColorCNFGSTRwithEq) Then tmpARR = Split(ReadSTR, "=") PensColor = tmpARR(1) ReflectPensColor() ''''''(tmpARR(1)) End If End If End If End While .Close() End With End If End Sub Public Sub WriteCNFG() WTS = New StreamWriter(CNFGFileName) With WTS .WriteLine(FormWidCNFGSTRwithEq + Trim(Str(FW))) .WriteLine(BackColorCNFGSTRwithEq + RedBack + CummaCHR + GreenBack + CummaCHR + BlueBack) .WriteLine(PensColorCNFGSTRwithEq + PensColor) .Close() End With End Sub Public Sub BackColorCMB_SelectedIndexChanged(sender As Object, e As EventArgs) Handles BackColorCMB.SelectedIndexChanged 'リストをクリックすると描画画面のバックカラーに直接反映 tune on VB2017 Select Case BackColorCMB.SelectedIndex Case 0 : RedBack = "255" : GreenBack = "255" : BlueBack = "255"'white Case 1 : RedBack = "064" : GreenBack = "064" : BlueBack = "064"'lampblack Case 2 : RedBack = "128" : GreenBack = "128" : BlueBack = "128"'paintgray Case 3 : RedBack = "064" : GreenBack = "128" : BlueBack = "064"'shoolboard Case 4 : RedBack = "128" : GreenBack = "255" : BlueBack = "128"'billiardgreen Case 5 : RedBack = "128" : GreenBack = "064" : BlueBack = "064"'brawn Case 6 : RedBack = "128" : GreenBack = "255" : BlueBack = "128"'brilliantgreen Case 7 : RedBack = "128" : GreenBack = "255" : BlueBack = "255"'waterBlue Case 8 : RedBack = "064" : GreenBack = "255" : BlueBack = "255"'brilliantwater Case 9 : RedBack = "128" : GreenBack = "128" : BlueBack = "255"'Bluepurple Case 10 : RedBack = "064" : GreenBack = "064" : BlueBack = "128"'indigo Case 11 : RedBack = "255" : GreenBack = "128" : BlueBack = "255"'redpurple Case 12 : RedBack = "255" : GreenBack = "064" : BlueBack = "255"'magenta Case 13 : RedBack = "255" : GreenBack = "064" : BlueBack = "064"'softred Case 14 : RedBack = "255" : GreenBack = "128" : BlueBack = "128"'salmonpink Case 15 : RedBack = "255" : GreenBack = "255" : BlueBack = "064"'softyellow Case 16 : RedBack = "255" : GreenBack = "255" : BlueBack = "128 " 'lemon End Select ReflectBackColor() WriteCNFG() End Sub Public Sub ReflectBackColor() GraPic.BackColor = Color.FromArgb( Val(RedBack), Val(GreenBack), Val(BlueBack)) End Sub Public Sub LineColorCMB_SelectedIndexChanged(sender As Object, e As EventArgs) Handles LineColorCMB.SelectedIndexChanged 'リストをクリックすると描画画面のpenカラーに直接反映 tune on VB2017 Select Case LineColorCMB.SelectedIndex Case 0 : p = Pens.White : PensColor = "White" Case 1 : p = Pens.Blue : PensColor = "Blue" Case 2 : p = Pens.Green : PensColor = "Green" Case 3 : p = Pens.Red : PensColor = "Red" Case 4 : p = Pens.Yellow : PensColor = "Yellow" Case 5 : p = Pens.Purple : PensColor = "Purple" Case 6 : p = Pens.LightBlue : PensColor = "LightBlue" Case 7 : p = Pens.Black : PensColor = "Black" End Select WriteCNFG() End Sub Public Sub ReflectPensColor() Select Case PensColor Case "White" : p = Pens.White Case "Blue" : p = Pens.Blue Case "Green" : p = Pens.Green Case "Red" : p = Pens.Red Case "Yellow" : p = Pens.Yellow Case "Purple" : p = Pens.Purple Case "LightBlue" : p = Pens.LightBlue Case "Black" : p = Pens.Black End Select End Sub Public Sub ExitBTN_Click(sender As Object, e As EventArgs) Handles ExitBTN.Click '普通に終了、つまり検証済み WriteCNFG() Me.Visible = False Me.Close() End Sub Public Sub Form_ReSize() 'フォームのサイズ変更に伴う論理//使っていない '何をしようとしているのかよくわからない 'よそから参照していないので検証はあとでいい Dim Ratewidth As Double Dim Rateheight As Double With Me If JustBeforeWidth = 0 Then JustBeforeWidth = .Width End If If JustBeforeHeight = 0 Then JustBeforeHeight = .Height End If Ratewidth = .Width / JustBeforeWidth Rateheight = .Height / JustBeforeHeight REM Call resizecontrol(control,WR,rh) End With End Sub Public Sub ReSizeContol( 'このルーチン意味ない?独立系につき検証はあとでいい<使っていない cont As Control, CLCMBflag As Boolean, Wr As Double, Rh As Double) With cont .Left = Int(Wr * .Left + 0.5) .Top = Int(Rh * .Top + 0.5) .Width = Int(Wr * .Width + 0.5) If CLCMBflag = False Then .Height = Int(Rh * .Height + 0.5) End If End With End Sub ' ==描画論理============================ ' 描画論理について ' このFoamの描画論理は、入力された ' xa,xb,ya,ybの矩形:ひとしくない正方形を、 '画面の正方形に無理やりはめ込むものになっ 'ている。この仕様は、マウスクリックで得た 'ピクセル座標からリアルの数値座標に変換す 'るために、出来るだけ単純でなければならな 'い要請からきている。 ' ' 逆に言えば、単純がゆえに数値空間と実装 'としてのピクチャオブジェクト間の変換はや 'さしい。せんだって複雑に考えてしまった論 '理を一度一掃し、改めて数式の類推を考えて 'ここにメモする。 ' ' またシステムのy軸は逆だということに留 '意。 ' ' 任意数値 x の pixelへの変換 'y も同様 ' < width > ' ' --------- ' | | ' | | ' | * ' | | | ' --------------- ' Xa x Xb '--->< x-Xa> ' Xa '----------> ' x ' < Xb-Xa > ' x-Xa pixelx x-Xa x-Xa ' ------- = ------- , pixelx = ------- * width = ------ * width ' Xb-Xa width Xb-Xa Xb-Xa ' x-Xa 'pixelx = ----- * width ' Xb-Xa '*マウスの点からreal数値へはこの逆演算 ' ' x-Xa pixelx pixelx pixelx ' -------- = ------ , ------ *(Xb-Xa) = x-Xa ,(Xb-Xa) * ------ + Xa = x ' Xb-Xa width width width ' pixelx 'realx:x = ------- * (Xb-Xa) + Xa ' width ' ' y pole : x=0 always anyway, ' ' then, ' from x=0 to pixelx case, ' -Xa 'pixelx = ----- * width, ' Xb-Xa 'line((pixelx,o)-(pixelx,height)) :VB6 gobj.drawline(pixelx,o,pixelx,width):.Net 'but x pole then needed height-pixely > pixely translation Public Sub PictureCLRBTN_Click(sender As Object, e As EventArgs) Handles pictureCLRBTN.Click PicRefresh() Call InputXYmojule() End Sub Public Sub minmaxTXTinit() MinXTXT.Text = CStr(-1) MaxXTXT.Text = CStr(+1) MinYTXT.Text = CStr(-1) MaxYTXT.Text = CStr(+1) End Sub Public Sub InputFromminmaxTXT() Xa = Val(MinXTXT.Text) Xb = Val(MaxXTXT.Text) Ya = Val(MinYTXT.Text) Yb = Val(MaxYTXT.Text) End Sub Public Function PixelfromReal(RealNum As Double, KindSTR As String) As Double Dim ResultNum As Double = 0 Dim AA As Double = 0 Dim BB As Double = 0 Dim PicScale = 1 InputFromminmaxTXT() With GraPic If KindSTR = "x" Or KindSTR = "X" Then AA = Xa BB = Xb PicScale = .Width Else If KindSTR = "y" Or KindSTR = "Y" Then AA = Ya BB = Yb PicScale = .Height End If End If End With If Not AA = BB Then ResultNum = PicScale * (RealNum - AA) / (BB - AA) End If PixelfromReal = ResultNum End Function Public Function RealFromPixel(PixelValue As Double, KindSTR As String) As Double Dim ResultNum As Double = 0 Dim AA As Double = 0 Dim BB As Double = 0 Dim PicScale = 1 InputFromminmaxTXT() If KindSTR = "x" Or KindSTR = "X" Then AA = Xa BB = Xb PicScale = GraPic.Width Else If KindSTR = "y" Or KindSTR = "Y" Then AA = Ya BB = Yb PicScale = GraPic.Height End If End If If Not AA = BB Then ResultNum = PixelValue * (BB - AA) / PicScale + AA End If RealFromPixel = ResultNum End Function Public Sub InputXYmojule() Dim px As VariantType 'for pixel data Dim py As VariantType '型を指定すると線を引くとき丸めエラーが出る 'X軸Y軸の補助線を引く。 'ピクチャオブジェクトの仕様が変わっているので未検証>検証済み InputFromminmaxTXT() With GraPic ' -x- px = PixelfromReal(0, "x") If 0 < px Then px = CInt(px) g.DrawLine(p, px, 0, px, .Height) 'vb2017 End If ' -y- py = PixelfromReal(0, "y") If 0 < py Then py = CInt(.Height - py) g.DrawLine(p, 0, py, .Width, py) 'vb2017 End If End With End Sub Public Sub GraPic_MouseDown(sender As Object, e As MouseEventArgs) Handles GraPic.MouseDown 'マウスクリックで描画画面の実数値を逆演算して取得し 'メッセージボックスに返す、マウスイベントの変更点:VB6>.netの調査がまだ>対応済み 'Dim XMSGReal As Double 'Dim YMSGReal As Double Dim x, y As Double Call InputFromminmaxTXT() With GraPic 'from pixel data to real num (not hardreal correctly) 'XMSGReal = Xa + (e.X / .Width) / (-Xa + Xb) 'YMSGReal = Ya - (e.Y / .Height) / (-Ya + Yb) 'y軸は逆さon display x = RealFromPixel(e.X, "x") y = RealFromPixel(.Height - e.Y, "y") MessageBox.Show('<無限小数のように表示、4桁程度にしたい:3桁、 "x " + CStr(ShisyaGonyu(x, 3)) + vbCrLf + "y " + CStr(ShisyaGonyu(y, 3)) ) End With FW = Me.Width FormCompRelocation() WriteCNFG() End Sub Public Function ShisyaGonyu(N As Double, Keta As Integer) As Double Dim AddFive As Single If N = 0 Then AddFive = 0 If N < 0 Then AddFive = -0.5 If 0 < N Then AddFive = +0.5 ShisyaGonyu = Int(N * 10 ^ Keta + AddFive) / (10 ^ Keta) End Function Public Sub CalcBTN_Click(sender As Object, e As EventArgs) Handles CalcBTN.Click 'グラフィックのための関数演算をxの範囲に従い '連続して行う。Foam1の複合関数を参照している。 '計算結果は値用 yの配列に格納、 '<初期設定、 10^3 個 10^5 可能、overflow or not 未チェック、 Dim Index, i As Integer ' Dim Xa_startendpoint, Xb_startendpoint As Integer Dim X As Double Dim tmpY As Double Dim tmpSTR As String = VacantCHR Dim tmpStepNum As Integer Dim MSGSTR As String Form1.NoUseGraphFormCHK.Checked = True '計算中は入出力をしない? If dot1000CHK.Checked = True Then CalcStepTXT.Text = "1000" End If TotalNumOfDeltaXinit() 'Dim Y(TotalNumOfDeltaX) '動的配列宣言うまくいかなかった For i = 0 To TotalNumOfDeltaX Y(i) = 0 Next i InputFromminmaxTXT() With CalcoutTXT .Text = VacantCHR MSGSTR = "入力最小値と最大値の順番が逆です。" + vbCrLf + " min and max, value sequence is different." If Xb < Xa Then MessageBox.Show("x: " + MSGSTR) Else If Yb < Ya Then MessageBox.Show("y: " + MSGSTR) Else DeltaXSmallSegmant = (-Xa + Xb) / TotalNumOfDeltaX tmpSTR = "elements num & step value :" + CStr(TotalNumOfDeltaX) + vbCrLf + CStr(DeltaXSmallSegmant) + vbCrLf '.text=.text+anystrという書き方だと 'loopエラーのような状態になる For Index = 0 To TotalNumOfDeltaX X = Xa + Index * DeltaXSmallSegmant tmpY = Form1.RealEngineAsFuncComplex(X) Y(Index) = tmpY tmpSTR = tmpSTR + CStr(X) + CummaCHR + CStr(tmpY) + vbCrLf Next Index End If End If .Text = tmpSTR End With End Sub Public Sub EXpressionBTN_click(sender As Object, e As EventArgs) Handles ExpressionBTN.Click '配列に格納された数値から画面に描画する Dim PictureXStep As Double 'Dim doublepY As Double '丸めエラーのために必要だった。ヴァリアント構造体使った。 'Dim DoublepX As Double Dim px As VariantType Dim py As VariantType Dim Index As Integer InputFromminmaxTXT() 'TotalNumOfDeltaX = 1000 With GraPic PictureXStep = .Width / TotalNumOfDeltaX For Index = 0 To TotalNumOfDeltaX ' < 1000 in first pX = Index * PictureXStep 'DoublepX = RealFromPixel(pX, "x") 'pX = doublepx 'いらない pY = PixelfromReal(Y(Index), "y") pY = .Height - pY 'doublepy If pY < 0 Or .Height < pY Then REM donothing Else g.drawellipse(p, pX, pY, 1, 1) End If Next Index End With End Sub ' 設定画面の保存に昵懇するのは賢明ではな 'い。問題は二つある。 ' コントロールごとにプロパティの種類によ 'って、あるプロパティがあったりなかったり 'する。その差異を残したまますべてのコンポ 'ーネントの設定を書き込もうとするのは乱暴。 ' 書き込みたいものは、チェックボックスの 'ブーリアン値程度、色彩に関しては、フルカ 'ラーコードを保存するのではなく、16色2 '56色の昔に帰り、指示文字列で反映させた '方が賢い。 ' コントロールの大きさは、Foamに依存した '関数を一つ用意しておけばこと足りる。 End Class '============================================================== ' ' File of End :Form4: ' '==============================================================