gogowaten.hatenablog.com
2日前の続き
今度こそ頂点の追加を修正した
直線以外の曲線も描画してみた
VBにはいろいろな線の描画があって簡単に変更できる
頂点の追加する時の判定方法を座標から角度に変えた
始点(0)から終点(3)まで順番につながった直線の
2と3の間をクリックして新頂点を追加する場合
0,1,2,3を
0,1,2,新(3)、4にしたい
目的は2の次に新を入れる
目で見れば簡単にわかるのにw
今まではそれぞれの直線をグラフの関数にして新頂点がそれに当てはまるかで
判定していたけどうまくいかないことがあるので他の方法…
今回は角度で判定
1から2の直線と1から新への直線の角度
2から3の直線と2から新への直線の角度
一番小さい角度が当たりってことにした
上の場合は2から3が当たりなので新頂点は2の次に入れればいいことになる
角度の出し方、求め方
だけど使い方がわからないというか
三角関数自体が理解できないので
どれをどう使えばいいのかわからないw
ググって
ここ
辺の名前はそれぞれ斜辺、隣辺、対辺
頂点の座標から簡単にわかる長さの辺は斜め以外の
隣辺と対辺
ラジアンとか知らないしわかりにくいので角度に変換は
エクセルならDEGREES関数に入れればいいだけ
角度 = 180 / Math.PI * radian
画像の描画ではyは普通のグラフと違って上下が逆になる
どこを0にするか、どっち周りにするか迷った
0度と359度の差は
360度と359度にしないとおかしいことにさっき気づいて
片方が0度の時もう片方が180度以上なら0度を360度で計算するようにとか
3日くらいかかった
これで間違えることは少なくなった
正確にするには実際に線が描画されている場所を計算するか
もっと別の方法かなあ
どちらも思いつかないのでもう今回のこれでいいや
Private Sub ToolStripMenuItem頂点の追加_Click(sender As Object, e As EventArgs) Handles ToolStripMenuItem頂点の追加.Click
Dim newPoint As New Point(mousePoint)
Dim ps As Generic.List(Of Point) = nowPic.PointN
Dim i As Long
Dim kakudo1, kakudo2 As Single
Dim oTaihen, oRinpen, nTaihen, nRinpen As Long
Dim aryKakudo As New ArrayList
Dim ore1 As New ArrayList
Dim ore2 As New ArrayList
For i = 0 To ps.Count - 2
oRinpen = ps(i + 1).X - ps(i).X
oTaihen = ps(i + 1).Y - ps(i).Y
nRinpen = newPoint.X - ps(i).X
nTaihen = newPoint.Y - ps(i).Y
kakudo1 = ore角度(oTaihen, oRinpen)
kakudo2 = ore角度(nTaihen, nRinpen)
If kakudo1 = 0 And kakudo2 >= 180 Then
kakudo1 = 360
ElseIf kakudo2 = 0 And kakudo1 >= 180 Then
kakudo2 = 360
End If
aryKakudo.Add(Math.Abs(kakudo1 - kakudo2))
ore1.Add(kakudo1)
ore2.Add(kakudo2)
Next
Dim min3 As Single = aryKakudo(0)
Dim idx As Long = 0
For i = 1 To UBound(aryKakudo.ToArray)
If min3 > aryKakudo(i) Then
idx = i
End If
Next
nowPic.PointN.Insert(idx + 1, newPoint)
Call 頂点の初期化(nowPic)
End Sub
座標から対辺と隣辺の長さを取得して↓の「ore角度」関数に送って
返ってきた角度を比較して新頂点を挿入
Private Function ore角度(Taihen As Long, Rinpen As Long) As Single
Dim kakudo As Single
If Taihen = 0 Or Rinpen = 0 Then
Select Case True
Case Taihen = 0 And Rinpen > 0
kakudo = 180
Case Taihen = 0 And Rinpen < 0
kakudo = 0
Case Taihen > 0 And Rinpen = 0
kakudo = 270
Case Taihen < 0 And Rinpen = 0
kakudo = 90
End Select
Else
Dim radian As Single
radian = Math.Atan(Taihen / Rinpen)
kakudo = 180 / Math.PI * radian
Select Case True
Case Taihen < 0 And Rinpen > 0
kakudo += 180
Case Taihen < 0 And Rinpen < 0
kakudo += 0
Case Taihen > 0 And Rinpen < 0
kakudo += 360
Case Taihen > 0 And Rinpen > 0
kakudo += 180
End Select
End If
Return kakudo
End Function
対辺と隣辺の長さを受け取って角度を返す「ore角度」関数
あまり使ったことがないselect caseが活躍、使い方あってるかな
参照したところ
ダウンロード
VisualBasic2013 - OneDrive
関連記事
今回のをもとにPixtack紫陽花に直線描画機能を追加
2014/12/24は1日後