トップ回答者
正多面体の正二十面体の作成の仕方

質問
回答
-
OpenTKを使ったことが無いのでGLEx.Faceが何をやっているコードなのか不明ですが、おそらく面を描画させているのだとすると、3面しか描画してないので20面には足らないですよね。
この直交する3つの四角形の12個の頂点を結ぶと正20面体ができるのでしょうから、そのように20個の3頂点を用意すればよいのではないでしょうか。C#でOpenTKのサンプルコードに手を加えてみると20面体になりますし
public HelloGL3() : base(640, 480, new GraphicsMode(), "OpenGL 3 Example", 0, DisplayDevice.Default, 3, 0, GraphicsContextFlags.ForwardCompatible | GraphicsContextFlags.Debug) { //正20面体の頂点座標を用意する float G = (float)((1.0 + Math.Sqrt(5)) * 0.5); Vector3[] vertexies = new Vector3[]{ new Vector3(1, G, 0), new Vector3(0, 1, G), new Vector3(G, 0, 1), new Vector3(-1, G, 0), new Vector3(0, -1, G), new Vector3(G, 0, -1), new Vector3(1, -G, 0), new Vector3(0, 1, -G), new Vector3(-G, 0, 1), new Vector3(-1, -G, 0), new Vector3(0, -1, -G), new Vector3(-G, 0, -1) }; //各頂点に直近の点の集合 List<int[]> listNear5 = vertexies.Select(a => vertexies.Select((b, i) => new { Index = i, LEN = (a - b).Length }).OrderBy(_ => _.LEN).Skip(1).Take(5).Select(_ => _.Index).OrderBy(_ => _).ToArray()).ToList(); //各頂点から作られる三角形の頂点のインデックスを集める List<int[]> list3 = new List<int[]>(); for (int i = 0; i < vertexies.Length; i++) { for (int j = 0; j < 5; j++) { for (int k = j + 1; k < 5; k++) { int p1 = listNear5[i][j]; int p2 = listNear5[i][k]; if (listNear5[p1].Contains(p2)) { int[] a = new int[] { i, p1, p2 }; Array.Sort(a); if (!list3.Any(b => b[0] == a[0] && b[1] == a[1] && b[2] == a[2])) { list3.Add(a); } } } } } List<int> indexies = new List<int>(); foreach (int[] a in list3) { indexies.AddRange(a); } //頂点座標と三角形の面のインデックス集合をサンプルコードに渡す positionVboData = vertexies; indicesVboData = indexies.ToArray(); }
個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)
- 編集済み gekkaMVP 2017年7月23日 10:55
- 回答の候補に設定 立花楓Microsoft employee, Moderator 2017年7月24日 1:10
- 回答としてマーク phy_6 2017年7月26日 9:59
-
/// Creates a 3D icosahedron of unit size using the current color let icosa = DF (fun ctx -> GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Diffuse, ctx.Color) GL.Begin(BeginMode.Triangles) let G = float32 ((1.0 + Math.Sqrt(5.0)) * 0.5) GLEx.Face ( 1.f, 0.f, G) [ ( 1.0f, 0.0f, G); ( 0.0f, -G, 1.0f); ( G, -1.0f, 0.0f); ( 1.0f, 0.0f, G); (-1.0f, 0.0f, G); ( 0.0f, -G, 1.0f); ( 1.0f, 0.0f, G); ( G, 1.0f, 0.0f); ( G, -1.0f, 0.0f); ( 1.0f, 0.0f, G); (-1.0f, 0.0f, G); ( 0.0f, G, 1.0f); ( 1.0f, 0.0f, G); ( 0.0f, G, 1.0f); ( G, 1.0f, 0.0f) ] GLEx.Face (G, 1.f, 0.f) [ ( G, 1.0f, 0.0f); ( G, -1.0f, 0.0f); ( 1.0f, 0.0f, -G) ] GLEx.Face (0.f, G, -1.f) [ ( 0.0f, G, -1.0f); (-1.0f, 0.0f, -G); ( 1.0f, 0.0f, -G); ( 0.0f, G, -1.0f); ( G, 1.0f, 0.0f); ( 1.0f, 0.0f, -G); ( 0.0f, G, -1.0f); ( G, 1.0f, 0.0f); ( 0.0f, G, 1.0f); ( 0.0f, G, -1.0f); ( 0.0f, G, 1.0f); (-G, 1.0f, 0.0f); ( 0.0f, G, -1.0f); (-G, 1.0f, 0.0f); (-1.0f, 0.0f, -G) ] GLEx.Face (-G, 1.f, 0.f) [ (-G, 1.0f, 0.0f); (-1.0f, 0.0f, G); ( 0.0f, G, 1.0f) ] GLEx.Face (-G, -1.f, 0.f) [ (-G, -1.0f, 0.0f); ( 0.0f, -G, 1.0f); (-1.0f, 0.0f, G); (-G, -1.0f, 0.0f); (-G, 1.0f, 0.0f); (-1.0f, 0.0f, -G); (-G, -1.0f, 0.0f); (-G, 1.0f, 0.0f); (-1.0f, 0.0f, G) ] GLEx.Face (0.f, -G, -1.f) [ ( 0.0f, -G, -1.0f); ( 0.0f, -G, 1.0f); ( G, -1.0f, 0.0f); ( 0.0f, -G, -1.0f); ( G, -1.0f, 0.0f); ( 1.0f, 0.0f, -G); ( 0.0f, -G, -1.0f); ( 1.0f, 0.0f, -G); (-1.0f, 0.0f, -G); ( 0.0f, -G, -1.0f); (-1.0f, 0.0f, -G); (-G, -1.0f, 0.0f); ( 0.0f, -G, -1.0f); (-G, -1.0f, 0.0f); ( 0.0f, -G, 1.0f) ] GL.End() )
libraryはこれを使って書きました。- 回答としてマーク phy_6 2017年8月18日 23:17
すべての返信
-
OpenTKを使ったことが無いのでGLEx.Faceが何をやっているコードなのか不明ですが、おそらく面を描画させているのだとすると、3面しか描画してないので20面には足らないですよね。
この直交する3つの四角形の12個の頂点を結ぶと正20面体ができるのでしょうから、そのように20個の3頂点を用意すればよいのではないでしょうか。C#でOpenTKのサンプルコードに手を加えてみると20面体になりますし
public HelloGL3() : base(640, 480, new GraphicsMode(), "OpenGL 3 Example", 0, DisplayDevice.Default, 3, 0, GraphicsContextFlags.ForwardCompatible | GraphicsContextFlags.Debug) { //正20面体の頂点座標を用意する float G = (float)((1.0 + Math.Sqrt(5)) * 0.5); Vector3[] vertexies = new Vector3[]{ new Vector3(1, G, 0), new Vector3(0, 1, G), new Vector3(G, 0, 1), new Vector3(-1, G, 0), new Vector3(0, -1, G), new Vector3(G, 0, -1), new Vector3(1, -G, 0), new Vector3(0, 1, -G), new Vector3(-G, 0, 1), new Vector3(-1, -G, 0), new Vector3(0, -1, -G), new Vector3(-G, 0, -1) }; //各頂点に直近の点の集合 List<int[]> listNear5 = vertexies.Select(a => vertexies.Select((b, i) => new { Index = i, LEN = (a - b).Length }).OrderBy(_ => _.LEN).Skip(1).Take(5).Select(_ => _.Index).OrderBy(_ => _).ToArray()).ToList(); //各頂点から作られる三角形の頂点のインデックスを集める List<int[]> list3 = new List<int[]>(); for (int i = 0; i < vertexies.Length; i++) { for (int j = 0; j < 5; j++) { for (int k = j + 1; k < 5; k++) { int p1 = listNear5[i][j]; int p2 = listNear5[i][k]; if (listNear5[p1].Contains(p2)) { int[] a = new int[] { i, p1, p2 }; Array.Sort(a); if (!list3.Any(b => b[0] == a[0] && b[1] == a[1] && b[2] == a[2])) { list3.Add(a); } } } } } List<int> indexies = new List<int>(); foreach (int[] a in list3) { indexies.AddRange(a); } //頂点座標と三角形の面のインデックス集合をサンプルコードに渡す positionVboData = vertexies; indicesVboData = indexies.ToArray(); }
個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)
- 編集済み gekkaMVP 2017年7月23日 10:55
- 回答の候補に設定 立花楓Microsoft employee, Moderator 2017年7月24日 1:10
- 回答としてマーク phy_6 2017年7月26日 9:59
-
どうやってと問われましてもOpenTKのどこにもないGLEx.Faceがどこから湧いて出てきたかわからないので変換しようがないですよ。
それでもエスパーしてみると
List<int> indexies = new List<int>(); foreach (int[] a in list3) { indexies.AddRange(a); System.Diagnostics.Debug.WriteLine("GLEx.Face\r\n\t{0}\r\n\t[{0};{1};{2}]", vertexies[a[0]], vertexies[a[1]], vertexies[a[2]]); }
な感じでやれば
GLEx.Face (1, 1.618034, 0) [(1, 1.618034, 0);(0, 1, 1.618034);(1.618034, 0, 1)] GLEx.Face (1, 1.618034, 0) [(1, 1.618034, 0);(0, 1, 1.618034);(-1, 1.618034, 0)] GLEx.Face (1, 1.618034, 0) [(1, 1.618034, 0);(1.618034, 0, 1);(1.618034, 0, -1)] GLEx.Face (1, 1.618034, 0) [(1, 1.618034, 0);(-1, 1.618034, 0);(0, 1, -1.618034)] GLEx.Face (1, 1.618034, 0) [(1, 1.618034, 0);(1.618034, 0, -1);(0, 1, -1.618034)] GLEx.Face (0, 1, 1.618034) [(0, 1, 1.618034);(1.618034, 0, 1);(0, -1, 1.618034)] 以下略
のような変換はできるんじゃないかな個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)
- 回答の候補に設定 立花楓Microsoft employee, Moderator 2017年7月24日 1:11
- 回答の候補の設定解除 phy_6 2017年7月25日 9:29
-
このライブラリを使ってフォーラムトップの図形を作成しました。
C#で改編しようとしたとき
Designer.csファイルとOpenTKの複数の形式が存在しないため
ビルドできないと出ました。
どういったところが作用してこの問題を作っているのか、
簡易な解決策を示していただけたらと思います。
-
F#やOpenTKは知らないので、申し訳ございませんが
よろしければ、お試しいただきたいことがございます。
正二十面体の頂点を簡単に求められる方法があったなんて上記サイトとphy_6様のロジックに使用しているパラメータは
同一ではないでしょうか?
そのため、パラメータの部分を次のように修正したのち
再度、実行してみてください。
※おそらく各頂点の設定値が正十二面体の頂点と異なる場所を
結んでしまったために生じたデザインになったものと推測しております。
GLEx.Face ( 1.0f, G, 0.0f) [ ( 1.0f, G, 0.0f); (-1.0f, G, 0.0f); ( 1.0f,-G, 0.0f); (-1.0f, -G, 0.0f) ] GLEx.Face ( G, 0.0f, 1.0f) [ ( G, 0.0f, 1.0f); ( G, 0.0f, -1.0f); (-G, 0.0f, 1.0f); (-G, 0.0f, -1.0f) ] GLEx.Face ( 0.0f, 1.0f, G) [ ( 0.0f, 1.0f, G); ( 0.0f,-1.0f, G); ( 0.0f, 1.0f,-G); ( 0.0f,-1.0f,-G) ]
-
正二十面体は20面と12頂点と30辺
BeginmodeはPolygonとTriangleとQuadしか描画できない
• GL TRIANGLES / GL QUADS: 3 あるいは 4 点を組にして,三角形あるいは四角形を描く.
• GL TRIANGLE STRIP / GL QUAD STRIP: 一辺を共有しながら帯状に三角形あるいは四角形を描く.
• GL TRIANGLE FAN: 一辺を共有しながら扇状に三角形を描く.
• GL POLYGON: 凸多角形を描く
これらに合わせた座標の書き方をするか
頭にあるのは
/// Creates a 3D sphere with unit size let sphere = DF (fun ctx -> GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Diffuse, ctx.Color) GL.Begin(BeginMode.Triangles) // points that will be used for generating the circle let q = float32 (Math.PI / (float quality / 2.0)) let circlePoints = [ for i in 0 .. quality -> sin(float32 i * q) * 0.5f, cos(float32 i * q) * 0.5f ] // points from the top to the bottom let heightPoints = [ for i in 0 .. quality -> sin(float32 i * q) * 0.5f, cos(float32 i * q) * 0.5f ] // Array (along one dimension) of circles let points = [| for hx, hy in heightPoints -> [| for x, y in circlePoints -> Vector3(x * hx * 2.0f, y * hx * 2.0f, hy) |] |] /// Generate the sphere for lat in 0 .. quality - 1 do for i in 0 .. quality - 1 do GL.Normal3 points.[lat].[i] GL.Vertex3 points.[lat].[i] GL.Normal3 points.[lat].[i+1] GL.Vertex3 points.[lat].[i+1] GL.Normal3 points.[lat+1].[i+1] GL.Vertex3 points.[lat+1].[i+1] GL.Normal3 points.[lat+1].[i+1] GL.Vertex3 points.[lat+1].[i+1] GL.Normal3 points.[lat+1].[i] GL.Vertex3 points.[lat+1].[i] GL.Normal3 points.[lat].[i] GL.Vertex3 points.[lat].[i] GL.End() )
表面積か体積を求めてしまい、実行させる方法です
正三角形を定義して作成、
そして12個の座標頂点に
当てはめる方法ってありますか?
Beginmode.Quadsで
立方体はGLEx.Faceの座標が24個
Beginmode.Trianglesで
正二十面体はGLEx.Faceの座標が60個
必須かなと。
後、F#の基礎もC#の基礎も押さえずに
進捗の話を進めていたので前、さゆりさんから
コンソールアプリケーションを作成しまくって
学習に勤しむべきだとの教示をもらったので
その通りにし、どういうメカニズムでこの言語は作動するのか?
というところにポイントを絞ってやっていこうと思います。
ソースコードと丁寧で簡潔な説明を書いていただき皆様ありがとうございました。
- 編集済み phy_6 2017年7月26日 10:20
-
/// Creates a 3D icosahedron of unit size using the current color let icosa = DF (fun ctx -> GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Diffuse, ctx.Color) GL.Begin(BeginMode.Triangles) let G = float32 ((1.0 + Math.Sqrt(5.0)) * 0.5) GLEx.Face ( 1.f, 0.f, G) [ ( 1.0f, 0.0f, G); ( 0.0f, -G, 1.0f); ( G, -1.0f, 0.0f); ( 1.0f, 0.0f, G); (-1.0f, 0.0f, G); ( 0.0f, -G, 1.0f); ( 1.0f, 0.0f, G); ( G, 1.0f, 0.0f); ( G, -1.0f, 0.0f); ( 1.0f, 0.0f, G); (-1.0f, 0.0f, G); ( 0.0f, G, 1.0f); ( 1.0f, 0.0f, G); ( 0.0f, G, 1.0f); ( G, 1.0f, 0.0f) ] GLEx.Face (G, 1.f, 0.f) [ ( G, 1.0f, 0.0f); ( G, -1.0f, 0.0f); ( 1.0f, 0.0f, -G) ] GLEx.Face (0.f, G, -1.f) [ ( 0.0f, G, -1.0f); (-1.0f, 0.0f, -G); ( 1.0f, 0.0f, -G); ( 0.0f, G, -1.0f); ( G, 1.0f, 0.0f); ( 1.0f, 0.0f, -G); ( 0.0f, G, -1.0f); ( G, 1.0f, 0.0f); ( 0.0f, G, 1.0f); ( 0.0f, G, -1.0f); ( 0.0f, G, 1.0f); (-G, 1.0f, 0.0f); ( 0.0f, G, -1.0f); (-G, 1.0f, 0.0f); (-1.0f, 0.0f, -G) ] GLEx.Face (-G, 1.f, 0.f) [ (-G, 1.0f, 0.0f); (-1.0f, 0.0f, G); ( 0.0f, G, 1.0f) ] GLEx.Face (-G, -1.f, 0.f) [ (-G, -1.0f, 0.0f); ( 0.0f, -G, 1.0f); (-1.0f, 0.0f, G); (-G, -1.0f, 0.0f); (-G, 1.0f, 0.0f); (-1.0f, 0.0f, -G); (-G, -1.0f, 0.0f); (-G, 1.0f, 0.0f); (-1.0f, 0.0f, G) ] GLEx.Face (0.f, -G, -1.f) [ ( 0.0f, -G, -1.0f); ( 0.0f, -G, 1.0f); ( G, -1.0f, 0.0f); ( 0.0f, -G, -1.0f); ( G, -1.0f, 0.0f); ( 1.0f, 0.0f, -G); ( 0.0f, -G, -1.0f); ( 1.0f, 0.0f, -G); (-1.0f, 0.0f, -G); ( 0.0f, -G, -1.0f); (-1.0f, 0.0f, -G); (-G, -1.0f, 0.0f); ( 0.0f, -G, -1.0f); (-G, -1.0f, 0.0f); ( 0.0f, -G, 1.0f) ] GL.End() )
libraryはこれを使って書きました。- 回答としてマーク phy_6 2017年8月18日 23:17