'ぷりスカ(R) 3Dモデル(XMLファイル形式)の作成 '製作・著作 (C)2021    オカダ・システムエンジニアリング研究所 Imports System.Windows.Media.Media3D Class MainWindow Dim rand1 As New Random 'プログラムはここから実行される Private Sub MainWindow_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded Dim obj1 As New ぷりスカ保存用10 Dim 系統 As Integer = 0 '0から始めること '書き込むファイル名 デスクトップ上の"test000.xml” Dim fileName = System.Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) & "\test000.xml" obj1.maker = "maker" obj1.name = "モデル名" obj1.content = "モデルコメント" '視点(カメラ位置)などの座標情報 obj1.view保存情報 = "-13.1648,0.1619,6.8127,0.0000,0.0000,0.0000,11.5098,1.3945,22.2083,-0.3983,25.0122,-1.3642,5.0000,0.0000,0.0000,0.0000,5.0000,0.0000,0.0000,0.0000,9.0000,-22.15,0.00,-9.23,72.33,0.0,80.0,0.63" ' makeテント(obj1, 系統) Dim i As Integer For i = 0 To 200 make桜の花びら(obj1, 系統) Next 'ファイルセーブ Dim serializer2 As New System.Xml.Serialization.XmlSerializer(GetType(ぷりスカ保存用10)) Using sw1 As New IO.StreamWriter(fileName, False, New System.Text.UTF8Encoding(False)) serializer2.Serialize(sw1, obj1) End Using Me.Close() End Sub Public Function 平行移動(ByVal p3 As Point3D, x As Single, y As Single, z As Single) As Point3D Dim si() As Single = {p3.X + x, p3.Y + y, p3.Z + z} Return New Point3D(si(0), si(1), si(2)) End Function Public Function 伸縮(ByVal p3 As Point3D, 倍率 As Single) As Point3D Dim si() As Single = {p3.X * 倍率, p3.Y * 倍率, p3.Z * 倍率} Return New Point3D(si(0), si(1), si(2)) End Function Public Function rotateF(ByVal p3 As Point3D, th_X As Single, th_Y As Single, th_Z As Single) As Point3D Dim si() As Single = {p3.X, p3.Y, p3.Z} Dim si2 = rotateF0(si, th_X, th_Y, th_Z) Return New Point3D(si2(0), si2(1), si2(2)) End Function '入力:3D座標のsingle()配列 3軸に回転 (単位:度) Public Function rotateF0(ByVal po As Single(), th_X As Single, th_Y As Single, th_Z As Single) As Single() Dim tx As Single = th_X * Math.PI * 2 / 360 Dim ty As Single = th_Y * Math.PI * 2 / 360 Dim tz As Single = th_Z * Math.PI * 2 / 360 Dim x, y, z As Single Dim r(2) As Single 'X軸の回転 x = po(0) y = po(1) z = po(2) r(0) = x r(1) = y * Math.Cos(tx) - z * Math.Sin(tx) r(2) = y * Math.Sin(tx) + z * Math.Cos(tx) 'Y軸の回転 x = r(0) y = r(1) z = r(2) r(0) = x * Math.Cos(ty) + z * Math.Sin(ty) r(1) = y r(2) = -x * Math.Sin(ty) + z * Math.Cos(ty) 'Z軸の回転 x = r(0) y = r(1) z = r(2) r(0) = x * Math.Cos(tz) - y * Math.Sin(tz) r(1) = x * Math.Sin(tz) + y * Math.Cos(tz) r(2) = z Return r End Function Private Sub makeテント(ByRef obj0 As ぷりスカ保存用10, ByVal 系統0 As Integer) Dim 登録点IX As New List(Of Integer) 'ハンドルポイント情報 登録点IX.Add(obj0.点add(New Point3D(-2.86, -3.98, -1.08), 系統0, True)) 登録点IX.Add(obj0.点add(New Point3D(2.26, -3.85, -0.7), 系統0, True)) 登録点IX.Add(obj0.点add(New Point3D(0, -4, 3), 系統0, True)) 登録点IX.Add(obj0.点add(New Point3D(0.22, -0.68, 0.7), 系統0, True)) 登録点IX.Add(obj0.点add(New Point3D(-2.63, -1.01, -0.63), 系統0, True)) '線連結情報 obj0.線2D.Add(New ぷりスカ保存用10.L2D(登録点IX(0), 0, 登録点IX(1), 1, 0)) '直線 実線 obj0.線2D.Add(New ぷりスカ保存用10.L2D(登録点IX(0), 0, 登録点IX(2), 1, 0)) obj0.線2D.Add(New ぷりスカ保存用10.L2D(登録点IX(0), 登録点IX(4), 登録点IX(3), 0, 1)) 'ベジエ 補助線 obj0.線2D.Add(New ぷりスカ保存用10.L2D(登録点IX(1), 0, 登録点IX(2), 1, 0)) obj0.線2D.Add(New ぷりスカ保存用10.L2D(登録点IX(1), 0, 登録点IX(3), 1, 0)) obj0.線2D.Add(New ぷりスカ保存用10.L2D(登録点IX(2), 0, 登録点IX(3), 1, 0)) '除外多角形があれば記述する obj0.除外多角形.Add("0,2,3") End Sub Private Sub make桜の花びら(ByRef obj0 As ぷりスカ保存用10, ByVal 系統0 As Integer) Dim 登録点IX As New List(Of Integer) 'ハンドルポイント情報 登録点IX.Add(obj0.点add(New Point3D(-1.97, -0.11, 2.04), 系統0, False)) '0 登録点IX.Add(obj0.点add(New Point3D(1.49, -0.36, -1.27), 系統0, False)) '1 登録点IX.Add(obj0.点add(New Point3D(2.41, -0.22, -1.27), 系統0, False)) '2 登録点IX.Add(obj0.点add(New Point3D(1.55, -0.27, -2.16), 系統0, False)) '3 登録点IX.Add(obj0.点add(New Point3D(-2.08, -0.1, -2.41), 系統0, False)) '4 登録点IX.Add(obj0.点add(New Point3D(2.51, -0.11, 2.44), 系統0, False)) '5 '線連結情報 obj0.線2D.Add(New ぷりスカ保存用10.L2D(登録点IX(0), 登録点IX(5), 登録点IX(2), 0, 0)) 'ベジエ 実線 obj0.線2D.Add(New ぷりスカ保存用10.L2D(登録点IX(0), 登録点IX(4), 登録点IX(3), 0, 0)) 'ベジエ 実線 obj0.線2D.Add(New ぷりスカ保存用10.L2D(登録点IX(1), 0, 登録点IX(2), 1, 0)) '直線 実線 obj0.線2D.Add(New ぷりスカ保存用10.L2D(登録点IX(1), 0, 登録点IX(3), 1, 0)) '直線 実線 '反り返り変形 Dim p31 As Point3D Dim i As Integer Dim x, y, z As Integer Dim x0, y0, z0, d As Single p31 = obj0.po3D(登録点IX(4)).p3 p31.Y += rand1.NextDouble * 3 - 1.3 obj0.po3D(登録点IX(4)).p3 = p31 p31 = obj0.po3D(登録点IX(5)).p3 p31.Y += rand1.NextDouble * 3 - 1.3 obj0.po3D(登録点IX(5)).p3 = p31 'ランダムに回転、拡大縮小、移動 x = rand1.NextDouble * 360 y = rand1.NextDouble * 360 z = rand1.NextDouble * 360 d = rand1.NextDouble + 0.3 x0 = rand1.NextDouble * 100 - 50 y0 = rand1.NextDouble * 100 - 50 z0 = rand1.NextDouble * 100 - 50 For i = 登録点IX(0) To 登録点IX(登録点IX.Count - 1) p31 = rotateF(obj0.po3D(i).p3, x, y, z) p31 = 伸縮(p31, d) p31 = 平行移動(p31, x0, y0, z0) '← ベクターを使用しなければダメか? obj0.po3D(i).p3 = p31 Next End Sub End Class 'ぷりスカ3Dモデルの保存用クラス Public Class ぷりスカ保存用10 '10はバージョン1.0であることを示す Public Property maker As String = "" Public Property name As String = "" Public Property content As String = "" Public Property view保存情報 As String Public Property 線2D As New List(Of L2D) Public Property po3D As New List(Of HP) Public Property 除外多角形 As New List(Of String) 'ハンドルポイントを追加 '既設の点と距離が近過ぎる場合(重複)は追加せず、既設の点のインデックスを返す 'Is重複統合  True:重複した場合は追加せずインデックスを返す False:常に追加 Public Function 点add(ByVal po3 As Point3D, ByVal 系統0 As Integer, ByVal Is重複統合 As Boolean) Dim v3 As Vector3D Dim i As Integer = 0 If Not Is重複統合 Then i = po3D.Count GoTo L100 End If For Each _hp As HP In po3D '既設の点配列についてサーチ v3 = New Vector3D(_hp.p3.X - po3.X, _hp.p3.Y - po3.Y, _hp.p3.Z - po3.Z) If v3.Length < 0.01 And _hp.tp = 0 And _hp.ch = 系統0 Then Return i '既設の点のインデックスを返す End If i += 1 Next L100: po3D.Add(New HP(po3, 系統0)) '新規に点を追加 新規のインデックスを返す Return i End Function Public Class L2D '線情報 Public Property tp1 As Integer '0:ベジエ 1:直線 Public Property tp2 As Integer 'type2:線2DType2 Public Property qix As Integer ' 起点Index Public Property cix As Integer ' 制御点Index Public Property zix As Integer ' 終点Index Public Sub New() 'これを消すと、~にはパラメータを持たないコンストラクタが含まれていないため、 'これをシリアル化することはできません。 のエラーで例外が発生する End Sub Public Sub New(ByVal 起点Index As Integer, ByVal 制御点Index As Integer, ByVal 終点Index As Integer, ByVal _type1 As Integer, ByVal _type2 As Integer) Me.qix = 起点Index Me.cix = 制御点Index Me.zix = 終点Index Me.tp1 = _type1 Me.tp2 = _type2 End Sub End Class Public Class HP 'ハンドルポイント情報 Public Property p3 As Point3D '3D形式座標 Public Property tp As Integer 'ハンドルポイント属性 ’ここは0を書き込むこと Public Property ch As Integer '系統 Public Sub New() 'これを消すと、~にはパラメータを持たないコンストラクタが含まれていないため、 'これをシリアル化することはできません。 のエラーで例外が発生する End Sub Public Sub New(ByVal _p3 As Point3D, ByVal _ch As Integer) Me.p3 = _p3 Me.tp = 0 Me.ch = _ch End Sub End Class End Class