忍者ブログ
[PR]
×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

【2024年04月29日05:36 】 |
C#3D立方体ワイヤーフレーム 座標ブッコミ(第2回) for VS2013 Express
C#3D立方体ワイヤーフレーム 座標ブッコミ(第2回) for VS2013 Express


C#3D立方体ワイヤーフレーム 序(第1回) for VS2013 Express

に続き2回目、

今回はCBondクラスを紹介する。
他のクラスはほぼ、変化はないがこのクラスを差し替えることで、
様々な立体情報を記述する事が出来る。



CBondクラス

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Drawing;
namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        class CBond
        {
            public CThreeD m_pThreeD;
            public Vertex m_Center = new Vertex();  //相対座標の中心
            List<Vertex> m_Vertex = new List<Vertex>();
            public int mGourp_num;      //グループ名の個数
            public CBond(int x, int y, int z, ref CThreeD pThreeD)
            {
                InitBond(x, y, z);
                m_pThreeD = pThreeD;
            }
            /*=============================================================================
             機能  初期化する
             引数  x, y, z : 
            =============================================================================*/
            public void InitBond(int x, int y, int z)
            {
                InitVertex(x - 1, y - 1, z - 1);
            }
            
            /*=============================================================================
             機能  頂点を初期化する
             引数  x, y, z : 立方体の番号( -1 ~ 1 )
            =============================================================================*/
            public void InitVertex(int x, int y, int z)
            {
                int cx, cy, cz;
                m_Center.x = 0;
                m_Center.y = 0;
                m_Center.z = 0;
                cx = 0; cy = 0; cz = 0;
                mGourp_num = 0;
                MyPoint3D[] A = new MyPoint3D[8];
                A[0] = new MyPoint3D(cx + 100, cy + 100, cz + 100);
                A[1] = new MyPoint3D(cx - 100, cy + 100, cz + 100);
                A[2] = new MyPoint3D(cx - 100, cy - 100, cz + 100);
                A[3] = new MyPoint3D(cx + 100, cy - 100, cz + 100);
                A[4] = new MyPoint3D(cx + 100, cy + 100, cz - 100);
                A[5] = new MyPoint3D(cx - 100, cy + 100, cz - 100);
                A[6] = new MyPoint3D(cx - 100, cy - 100, cz - 100);
                A[7] = new MyPoint3D(cx + 100, cy - 100, cz - 100);
                //コネクト情報
                
                A[0].bond.Add(1);
                A[1].bond.Add(2);
                A[2].bond.Add(3);
                A[3].bond.Add(0);
                
                
                A[4].bond.Add(5);
                A[5].bond.Add(6);
                A[6].bond.Add(7);
                A[7].bond.Add(4);
                
                A[0].bond.Add(4);
                A[1].bond.Add(5);
                A[2].bond.Add(6);
                A[3].bond.Add(7);
                
                List<MyPoint3D> result = new List<MyPoint3D>();
                
                //格納
                for (int i = 0; 8 > i; i++)
                {
                    result.Add(A[i]);
                }
                for (int i = 0; result.Count > i; i++)
                {
                    
                    SetVertex(0, i, result[i].bond, result[i].x, result[i].y, result[i].z);
                    
                }
                
            }
            /*=============================================================================
             機能  頂点を決める
             引数     group: グループ番号
                         n : 線の番号
                         m : どこと繋がるか
                   x, y, z : 端の座標
            =============================================================================*/
            public void SetVertex(int group, int n, List<int> bond, int x, int y, int z)
            {
                
                Vertex ver = new Vertex();
                ver.group = group;
                for (int i = 0; bond.Count > i; i++) ver.bond.Add(bond[i]);
                
                ver.x = x;
                ver.y = y;
                ver.z = z;
                m_Vertex.Add(ver);
            }
            /*=============================================================================
             機能  2次元座標系に変換する(回転行列をつくる)
             引数  ViewPolar : 視点の極座標
            =============================================================================*/
            public void TransferScreen(Polar ViewPolar)
            {
                int i;
                Vertex ver = new Vertex();
                for (i = 0; i < m_Vertex.Count; i++)
                {
                    if (m_Vertex[i] != null)
                    {
                        ver = m_Vertex[i];
                        m_pThreeD.TransferScreen(ViewPolar, ref ver);
                        m_Vertex[i] = ver;
                    }
                }
            }
            /*=============================================================================
             機能  立方体を描画する
             引数  pDC        : メモリデバイスコンテキストへのポインタ
                   ViewVertex : 視点の座標
            =============================================================================*/
            public void DrawBond(Graphics gra, Pen pen, Vertex ViewVertex)
            {
                int i,j;
                Point[] point = new Point[2];
                i = 0;
                for (i = 0; i < m_Vertex.Count; i++)
                {
                    if (m_Vertex[i] != null)
                    {
                        for (j = 0; j < m_Vertex[i].bond.Count; j++)
                        {
                            int c = m_Vertex[i].bond[j]; //接続先
                            
                            point[0].X = m_Center.x + m_Vertex[i].point.X;
                            point[0].Y = m_Center.y + m_Vertex[i].point.Y;
                            point[1].X = m_Center.x + m_Vertex[c].point.X;
                            point[1].Y = m_Center.y + m_Vertex[c].point.Y;
                            
                            
                            gra.DrawLine(pen, point[0], point[1]);
                            
                        }
                    }
                }
            }
        }
    }
}



DrawBond   ・・・描画
TransferScreen ・・・座標を2次元に投影。CThreeDクラスに投げる。
SetVertex    ・・・座標情報を格納
InitVertex    ・・・初期の座標情報を作成
CBond     ・・・このプログラムの最初に呼び出される。


立方体なので、サイコロを思い出して欲しいのですが
頂点が8個あるので

MyPoint3D[] A = new MyPoint3D[8];

で、8個の座標を格納する MyPoint3D型 を生成している。

 


                A[0] = new MyPoint3D(cx + 100, cy + 100, cz + 100);
                A[1] = new MyPoint3D(cx - 100, cy + 100, cz + 100);
                A[2] = new MyPoint3D(cx - 100, cy - 100, cz + 100);
                A[3] = new MyPoint3D(cx + 100, cy - 100, cz + 100);
                A[4] = new MyPoint3D(cx + 100, cy + 100, cz - 100);
                A[5] = new MyPoint3D(cx - 100, cy + 100, cz - 100);
                A[6] = new MyPoint3D(cx - 100, cy - 100, cz - 100);
                A[7] = new MyPoint3D(cx + 100, cy - 100, cz - 100);

A[0]から、A[7]には図に示す通り、立方体の頂点を格納した。
cx,cy,czは、この塊を動かす際に用いる。


                //コネクト情報
                
                A[0].bond.Add(1);
                A[1].bond.Add(2);
                A[2].bond.Add(3);
                A[3].bond.Add(0);
                :

コネクト情報で、どの点と点を結ぶか情報を与えている。
第一回でも述べたが、bondはList<int>なのでAddで追加可能だ。


                List<MyPoint3D> result = new List<MyPoint3D>();
                
                //格納
                for (int i = 0; 8 > i; i++)
                {
                    result.Add(A[i]);
                }
                for (int i = 0; result.Count > i; i++)
                {
                    
                    SetVertex(0, i, result[i].bond, result[i].x, result[i].y, result[i].z);
                    
                }
resultに再度入れているが、ここは別に必要ないが
List型に入れとくと便利なので使用。

            List<Vertex> m_Vertex = new List<Vertex>();
 
SetVertex()で、List<Vertex> の m_Vertex に座標を格納。


   public void TransferScreen(Polar ViewPolar)
            {
                int i;
                Vertex ver = new Vertex();
                for (i = 0; i < m_Vertex.Count; i++)
                {
                    if (m_Vertex[i] != null)
                    {
                        ver = m_Vertex[i];
                        m_pThreeD.TransferScreen(ViewPolar, ref ver);
                        m_Vertex[i] = ver;
                    }
                }
            }


TransferScreen()関数でList<Vertex> の m_Vertex に格納した座標を
マウスが上下に動かした分を、それぞれ角度に見立て、極座標を直行座標に変換し
X軸固定回転、Y軸固定回転のマトリックスで座標変換。

参照 C#3D立方体ワイヤーフレーム 序(第1回) for VS2013 Express



   public void DrawBond(Graphics gra, Pen pen, Vertex ViewVertex)
            {
                int i,j;
                Point[] point = new Point[2];
                i = 0;
                for (i = 0; i < m_Vertex.Count; i++)
                {
                    if (m_Vertex[i] != null)
                    {
                        for (j = 0; j < m_Vertex[i].bond.Count; j++)
                        {
                            int c = m_Vertex[i].bond[j]; //接続先
                            
                            point[0].X = m_Center.x + m_Vertex[i].point.X;
                            point[0].Y = m_Center.y + m_Vertex[i].point.Y;
                            point[1].X = m_Center.x + m_Vertex[c].point.X;
                            point[1].Y = m_Center.y + m_Vertex[c].point.Y;
                            
                            
                            gra.DrawLine(pen, point[0], point[1]);
                            
                        }
                    }
                }
            }


List<Vertex> の m_Vertex に格納した座標の要素分(m_Vertex[i].bond.Count;
のそれぞれの座標に接続するラインを

gra.DrawLine(pen, point[0], point[1]);


で描画している。

このクラスをいろいろいじると様々な立体を3D化出来るので
一番楽しいところだ。

次の第三回は CRubic クラス。



終わり。

PR
【2016年09月11日18:54 】 | グラフィック | コメント(0)
コメントの投稿













前ページ | ホーム | 次ページ

忍者ブログ [PR]