//等しいか判定 public static bool Ecoal(Vector3D A, Vector3D B) { if (A.X == B.X && A.Y == B.Y && A.Z == B.Z) return true; else return false; }
//誤差の範囲内かを判定 public static bool NearlyEcoal(Vector3D A, Vector3D B, float errorrange) { if (Math.Abs(A.X - B.X) < errorrange && Math.Abs(A.Y - B.Y) < errorrange && Math.Abs(A.Z - B.Z) < errorrange) return true; else return false; }
float w, h; //w:幅, h:高さ #endregion Fields #region Constructors //コンストラクタ public osCamera() { Upward = new Vector3D(); Setposition = new Vector3D(); LookatPoint = new Vector3D(); CameraX = new Vector3D(); CameraY = new Vector3D(); CameraZ = new Vector3D(); Light = new Vector3D(); rotatematrix = new Matrix(3); projectionmatrix = new Matrix(3); Upward.X = 0.0f; Upward.Y = 0.0f; Upward.Z = 1.0f; Setposition.X = 100.0f; Setposition.Y = 300.0f; Setposition.Z = 100.0f; LookatPoint.X = 0.0f; LookatPoint.Y = 0.0f; LookatPoint.Z = 0.0f; temp2 = new Vector3D(-Setposition.X, -Setposition.Y, LookatPoint.Z); r = Setposition.Getnorm(); alpha = Math.Atan(Setposition.Y / Setposition.X); beta = Math.Asin((double)Setposition.Z / r); Light.X = 50.0f; Light.Y = 60.0f; Light.Z = 100.0f; angle = Math.PI / 3.0; aspect = 1.0f; nearZ = 10.0f; farZ = 20.0f; }
//ベクトル*行列 public static Vector3D operator *(Vector3D A, Matrix B) { Vector3D temp = new Vector3D(); temp.X = A.X * B.matrix[0, 0] + A.Y * B.matrix[1, 0] + A.Z * B.matrix[2, 0]; temp.Y = A.X * B.matrix[0, 1] + A.Y * B.matrix[1, 1] + A.Z * B.matrix[2, 1]; temp.Z = A.X * B.matrix[0, 2] + A.Y * B.matrix[1, 2] + A.Z * B.matrix[2, 2]; return temp; }
//コンストラクタ(引数:3D座標) public Vertex(float x, float y, float z) { center2D = new Vector2D(); center3D = new Vector3D(x, y, z); brush = new SolidBrush(Color.Black); isSelected = false; willSelected = false; viewOK = false; diameter = 8; neighbor = new List<Vertex>(); nearlyNeighbor = new List<Vertex>(); }
int vertices_num; //頂点数 #endregion Fields #region Constructors //コンストラクタ public osPolygon(int i) { FaceNum = i; isVisible = false; start_vertex = new Vertex(0, 0); end_vertex = new Vertex(0, 0); vertex = new List<Vertex>(); edge = new List<Edge>(); nowbrush = new SolidBrush(Color.Red); basebrush = new SolidBrush(Color.Red); vertices_num = 0; isOpened = false; center = new Vector3D(0, 0, 0); normal = new Vector3D(); }
//座標を設定 public Vector3D(Vector3D vtr3D) { this.Set(vtr3D.X, vtr3D.Y, vtr3D.Z); }
//2つのベクトルの距離を取得 public float Getdistance(Vector3D A) { return (A - this).Getnorm(); }
//軸回転行列の生成 public void Set_Rotate_ArbAx(Vector3D n, double angle) { this.matrix[0, 0] = (float)(n.X * n.X + (1 - n.X * n.X) * Math.Cos(angle)); this.matrix[1, 0] = (float)(n.X * n.Y * (1 - Math.Cos(angle)) - n.Z * Math.Sin(angle)); this.matrix[2, 0] = (float)(n.Z * n.X * (1 - Math.Cos(angle)) + n.Y * Math.Sin(angle)); this.matrix[0, 1] = (float)(n.X * n.Y * (1 - Math.Cos(angle)) + n.Z * Math.Sin(angle)); this.matrix[1, 1] = (float)(n.Y * n.Y + (1 - n.Y * n.Y) * Math.Cos(angle)); this.matrix[2, 1] = (float)(n.Y * n.Z * (1 - Math.Cos(angle)) - n.X * Math.Sin(angle)); this.matrix[0, 2] = (float)(n.Z * n.X * (1 - Math.Cos(angle)) - n.Y * Math.Sin(angle)); this.matrix[1, 2] = (float)(n.Y * n.Z * (1 - Math.Cos(angle)) + n.X * Math.Sin(angle)); this.matrix[2, 2] = (float)(n.Z * n.Z + (1 - n.Z * n.Z) * Math.Cos(angle)); }
//正八面体を生成 private void SetOctahedron(float length) { Face3D.Clear(); Dual.Clear(); Vector3D[] Vtemp = new Vector3D[6]; osPolygon Ptemp; for (int i = 0; i < 6; i++) Vtemp[i] = new Vector3D(); Vtemp[0].Set(0.0f, 0.0f, length / (float)Math.Sqrt(2.0)); Vtemp[1].Set(length / 2, length / 2, 0.0f); Vtemp[2].Set(-length / 2, length / 2, 0.0f); Vtemp[3].Set(-length / 2, -length / 2, 0.0f); Vtemp[4].Set(length / 2, -length / 2, 0.0f); Vtemp[5].Set(0.0f, 0.0f, -length / (float)Math.Sqrt(2.0)); Ptemp = new osPolygon(0); Ptemp.AddVertex(Vtemp[0]); Ptemp.AddVertex(Vtemp[1]); Ptemp.AddVertex(Vtemp[2]); Face3D.Add(Ptemp); Ptemp = new osPolygon(1); Ptemp.AddVertex(Vtemp[0]); Ptemp.AddVertex(Vtemp[2]); Ptemp.AddVertex(Vtemp[3]); Face3D.Add(Ptemp); Ptemp = new osPolygon(2); Ptemp.AddVertex(Vtemp[0]); Ptemp.AddVertex(Vtemp[3]); Ptemp.AddVertex(Vtemp[4]); Face3D.Add(Ptemp); Ptemp = new osPolygon(3); Ptemp.AddVertex(Vtemp[0]); Ptemp.AddVertex(Vtemp[4]); Ptemp.AddVertex(Vtemp[1]); Face3D.Add(Ptemp); Ptemp = new osPolygon(4); Ptemp.AddVertex(Vtemp[5]); Ptemp.AddVertex(Vtemp[2]); Ptemp.AddVertex(Vtemp[1]); Face3D.Add(Ptemp); Ptemp = new osPolygon(5); Ptemp.AddVertex(Vtemp[5]); Ptemp.AddVertex(Vtemp[3]); Ptemp.AddVertex(Vtemp[2]); Face3D.Add(Ptemp); Ptemp = new osPolygon(6); Ptemp.AddVertex(Vtemp[5]); Ptemp.AddVertex(Vtemp[4]); Ptemp.AddVertex(Vtemp[3]); Face3D.Add(Ptemp); Ptemp = new osPolygon(7); Ptemp.AddVertex(Vtemp[5]); Ptemp.AddVertex(Vtemp[1]); Ptemp.AddVertex(Vtemp[4]); Face3D.Add(Ptemp); List<Vector3D> temp = new List<Vector3D>(); for (int i = 0; i < Face3D.Count; i++) { Face3D[i].SetCenter(); temp.Add(Face3D[i].center); } for (int i = 0; i < temp.Count; i++) Dual.Add(new Vertex(temp[i].X, temp[i].Y, temp[i].Z)); Dual[0].SetNeighbor(Dual[4]); Dual[0].SetNeighbor(Dual[1]); Dual[0].SetNeighbor(Dual[3]); Dual[1].SetNeighbor(Dual[5]); Dual[1].SetNeighbor(Dual[0]); Dual[1].SetNeighbor(Dual[2]); Dual[2].SetNeighbor(Dual[6]); Dual[2].SetNeighbor(Dual[1]); Dual[2].SetNeighbor(Dual[3]); Dual[3].SetNeighbor(Dual[7]); Dual[3].SetNeighbor(Dual[0]); Dual[3].SetNeighbor(Dual[2]); Dual[4].SetNeighbor(Dual[0]); Dual[4].SetNeighbor(Dual[5]); Dual[4].SetNeighbor(Dual[7]); Dual[5].SetNeighbor(Dual[1]); Dual[5].SetNeighbor(Dual[4]); Dual[5].SetNeighbor(Dual[6]); Dual[6].SetNeighbor(Dual[2]); Dual[6].SetNeighbor(Dual[5]); Dual[6].SetNeighbor(Dual[7]); Dual[7].SetNeighbor(Dual[3]); Dual[7].SetNeighbor(Dual[4]); Dual[7].SetNeighbor(Dual[6]); }
//任意の点の回転 public void RotatePoint(Vector3D n, ref Vector3D v, float a) { rotatematrix.Set_Rotate_ArbAx(n, a); v = v * rotatematrix; }
//可視判定 public double Hidden(Vector3D vtr3D) { Vector3D vector1 = new Vector3D(); Vector3D vector2 = new Vector3D(); Vector3D outer = new Vector3D(); Vector3D S = new Vector3D(); double cos; vector1 = vertex[2].center3D - vertex[0].center3D; vector2 = vertex[1].center3D - vertex[0].center3D; outer = Vector3D.Outer(vector1, vector2); S = vertex[0].center3D - vtr3D; outer.Normalization(); S.Normalization(); cos = Vector3D.Inner(S, outer); if (cos < 0) { outer = Vector3D.Outer(vector2, vector1); outer.Normalization(); S.Normalization(); cos = Vector3D.Inner(S, outer); } return cos; }
//正十二面体を生成 private void SetDodecahedron(float length) { SetIcosahedron(length); List<Vector3D> temp = new List<Vector3D>(); for (int i = 0; i < Face3D.Count; i++) { Face3D[i].SetCenter(); temp.Add(Face3D[i].center); } Face3D.Clear(); Dual.Clear(); Vector3D[] Vtemp = new Vector3D[20]; osPolygon Ptemp; for (int i = 0; i < 20; i++) Vtemp[i] = new Vector3D(); Ptemp = new osPolygon(0); Ptemp.AddVertex(temp[0]); Ptemp.AddVertex(temp[10]); Ptemp.AddVertex(temp[11]); Ptemp.AddVertex(temp[12]); Ptemp.AddVertex(temp[1]); Face3D.Add(Ptemp); Ptemp = new osPolygon(1); Ptemp.AddVertex(temp[1]); Ptemp.AddVertex(temp[12]); Ptemp.AddVertex(temp[13]); Ptemp.AddVertex(temp[14]); Ptemp.AddVertex(temp[2]); Face3D.Add(Ptemp); Ptemp = new osPolygon(2); Ptemp.AddVertex(temp[2]); Ptemp.AddVertex(temp[14]); Ptemp.AddVertex(temp[15]); Ptemp.AddVertex(temp[16]); Ptemp.AddVertex(temp[3]); Face3D.Add(Ptemp); Ptemp = new osPolygon(3); Ptemp.AddVertex(temp[3]); Ptemp.AddVertex(temp[16]); Ptemp.AddVertex(temp[17]); Ptemp.AddVertex(temp[18]); Ptemp.AddVertex(temp[4]); Face3D.Add(Ptemp); Ptemp = new osPolygon(4); Ptemp.AddVertex(temp[4]); Ptemp.AddVertex(temp[18]); Ptemp.AddVertex(temp[19]); Ptemp.AddVertex(temp[10]); Ptemp.AddVertex(temp[0]); Face3D.Add(Ptemp); Ptemp = new osPolygon(5); Ptemp.AddVertex(temp[6]); Ptemp.AddVertex(temp[13]); Ptemp.AddVertex(temp[12]); Ptemp.AddVertex(temp[11]); Ptemp.AddVertex(temp[5]); Face3D.Add(Ptemp); Ptemp = new osPolygon(6); Ptemp.AddVertex(temp[7]); Ptemp.AddVertex(temp[15]); Ptemp.AddVertex(temp[14]); Ptemp.AddVertex(temp[13]); Ptemp.AddVertex(temp[6]); Face3D.Add(Ptemp); Ptemp = new osPolygon(7); Ptemp.AddVertex(temp[8]); Ptemp.AddVertex(temp[17]); Ptemp.AddVertex(temp[16]); Ptemp.AddVertex(temp[15]); Ptemp.AddVertex(temp[7]); Face3D.Add(Ptemp); Ptemp = new osPolygon(8); Ptemp.AddVertex(temp[9]); Ptemp.AddVertex(temp[19]); Ptemp.AddVertex(temp[18]); Ptemp.AddVertex(temp[17]); Ptemp.AddVertex(temp[8]); Face3D.Add(Ptemp); Ptemp = new osPolygon(9); Ptemp.AddVertex(temp[5]); Ptemp.AddVertex(temp[11]); Ptemp.AddVertex(temp[10]); Ptemp.AddVertex(temp[19]); Ptemp.AddVertex(temp[9]); Face3D.Add(Ptemp); Ptemp = new osPolygon(10); Ptemp.AddVertex(temp[0]); Ptemp.AddVertex(temp[1]); Ptemp.AddVertex(temp[2]); Ptemp.AddVertex(temp[3]); Ptemp.AddVertex(temp[4]); Face3D.Add(Ptemp); Ptemp = new osPolygon(11); Ptemp.AddVertex(temp[9]); Ptemp.AddVertex(temp[8]); Ptemp.AddVertex(temp[7]); Ptemp.AddVertex(temp[6]); Ptemp.AddVertex(temp[5]); Face3D.Add(Ptemp); temp.Clear(); for (int i = 0; i < Face3D.Count; i++) { Face3D[i].SetCenter(); temp.Add(Face3D[i].center); } for (int i = 0; i < temp.Count; i++) Dual.Add(new Vertex(temp[i].X, temp[i].Y, temp[i].Z)); Dual[0].SetNeighbor(Dual[10]); Dual[0].SetNeighbor(Dual[4]); Dual[0].SetNeighbor(Dual[1]); Dual[0].SetNeighbor(Dual[5]); Dual[0].SetNeighbor(Dual[9]); Dual[1].SetNeighbor(Dual[10]); Dual[1].SetNeighbor(Dual[0]); Dual[1].SetNeighbor(Dual[2]); Dual[1].SetNeighbor(Dual[6]); Dual[1].SetNeighbor(Dual[5]); Dual[2].SetNeighbor(Dual[10]); Dual[2].SetNeighbor(Dual[1]); Dual[2].SetNeighbor(Dual[3]); Dual[2].SetNeighbor(Dual[7]); Dual[2].SetNeighbor(Dual[6]); Dual[3].SetNeighbor(Dual[10]); Dual[3].SetNeighbor(Dual[2]); Dual[3].SetNeighbor(Dual[4]); Dual[3].SetNeighbor(Dual[8]); Dual[3].SetNeighbor(Dual[7]); Dual[4].SetNeighbor(Dual[10]); Dual[4].SetNeighbor(Dual[3]); Dual[4].SetNeighbor(Dual[0]); Dual[4].SetNeighbor(Dual[9]); Dual[4].SetNeighbor(Dual[8]); Dual[5].SetNeighbor(Dual[11]); Dual[5].SetNeighbor(Dual[9]); Dual[5].SetNeighbor(Dual[6]); Dual[5].SetNeighbor(Dual[0]); Dual[5].SetNeighbor(Dual[1]); Dual[6].SetNeighbor(Dual[11]); Dual[6].SetNeighbor(Dual[5]); Dual[6].SetNeighbor(Dual[7]); Dual[6].SetNeighbor(Dual[1]); Dual[6].SetNeighbor(Dual[2]); Dual[7].SetNeighbor(Dual[11]); Dual[7].SetNeighbor(Dual[6]); Dual[7].SetNeighbor(Dual[8]); Dual[7].SetNeighbor(Dual[2]); Dual[7].SetNeighbor(Dual[3]); Dual[8].SetNeighbor(Dual[11]); Dual[8].SetNeighbor(Dual[7]); Dual[8].SetNeighbor(Dual[9]); Dual[8].SetNeighbor(Dual[3]); Dual[8].SetNeighbor(Dual[4]); Dual[9].SetNeighbor(Dual[11]); Dual[9].SetNeighbor(Dual[8]); Dual[9].SetNeighbor(Dual[5]); Dual[9].SetNeighbor(Dual[4]); Dual[9].SetNeighbor(Dual[0]); Dual[10].SetNeighbor(Dual[0]); Dual[10].SetNeighbor(Dual[1]); Dual[10].SetNeighbor(Dual[2]); Dual[10].SetNeighbor(Dual[3]); Dual[10].SetNeighbor(Dual[4]); Dual[11].SetNeighbor(Dual[5]); Dual[11].SetNeighbor(Dual[6]); Dual[11].SetNeighbor(Dual[7]); Dual[11].SetNeighbor(Dual[8]); Dual[11].SetNeighbor(Dual[9]); }
//スクリーン座標変換 public Vector3D ViewTranslate(Vector3D A) { Vector3D P = new Vector3D(); P.X = Vector3D.Inner(A, CameraX) - Vector3D.Inner(Setposition, CameraX); P.Y = Vector3D.Inner(A, CameraY) - Vector3D.Inner(Setposition, CameraY); P.Z = Vector3D.Inner(A, CameraZ) - Vector3D.Inner(Setposition, CameraZ); return P; }
//ビューポート変換 public Vector2D ViewPortTranslate(Vector3D A) { Vector2D P = new Vector2D(); P.X = (float)(A.X * (w / 2) + (w / 2)); P.Y = (float)(A.Y * -(h / 2) + (h / 2)); return P; }
//一括座標変換(関数オーバロード) public Vector2D Translate(Vector3D A) { Vector3D P = new Vector3D(); Vector2D R = new Vector2D(); P = ViewTranslate(A); P = ProjectionTranslate(P); R = ViewPortTranslate(P); return R; }
//一括座標変換(関数オーバロード) public Vertex[] Translate(Vertex[] A) { int len = A.Length; Vector3D[] P = new Vector3D[len]; Vector2D[] R = new Vector2D[len]; Vector3D[] Pt = new Vector3D[len]; Vertex[] Rt = new Vertex[len]; for (int i = 0; i < len; i++) { P[i] = new Vector3D(); R[i] = new Vector2D(); Pt[i] = new Vector3D(); Rt[i] = new Vertex(0, 0); } for (int i = 0; i < len; i++) { Pt[i] = A[i].center3D; } for (int i = 0; i < len; i++) { P[i] = ViewTranslate(Pt[i]); P[i] = ProjectionTranslate(P[i]); R[i] = ViewPortTranslate(P[i]); } for (int i = 0; i < len; i++) { Rt[i].center3D = Pt[i]; Rt[i].center2D = R[i]; } return Rt; }
//一括座標変換 public Vector2D[] Translate(Vector3D[] A) { int len = A.Length; Vector3D[] P = new Vector3D[len]; Vector2D[] R = new Vector2D[len]; for (int i = 0; i < len; i++) { P[i] = new Vector3D(); R[i] = new Vector2D(); } for (int i = 0; i < len; i++) { P[i] = ViewTranslate(A[i]); P[i] = ProjectionTranslate(P[i]); R[i] = ViewPortTranslate(P[i]); } return R; }
//カメラ座標の設定 public void SetCaemraAxes() { CameraZ = LookatPoint - Setposition; CameraZ.Normalization(); CameraX = Vector3D.Outer(Upward, CameraZ); CameraX.Normalization(); CameraY = Vector3D.Outer(CameraZ, CameraX); }
//正二十面体を生成 private void SetIcosahedron(float length) { Face3D.Clear(); Dual.Clear(); Vector3D[] Vtemp = new Vector3D[12]; osPolygon Ptemp; Vector2D temp1 = new Vector2D(); double Ztemp1, Ztemp2; for (int i = 0; i < 12; i++) Vtemp[i] = new Vector3D(); Ztemp1 = (length / (2.0 * Math.Sin(Math.PI / 5.0))); Ztemp1 = Math.Sqrt(length * length - Ztemp1 * Ztemp1); Ztemp2 = Math.Sqrt((length * Math.Cos(Math.PI / 6.0)) * (length * Math.Cos(Math.PI / 6.0)) - (length / (2 * Math.Sin(Math.PI / 5.0)) - length / (2 * Math.Tan(Math.PI / 5.0))) * (length / (2 * Math.Sin(Math.PI / 5.0)) - length / (2 * Math.Tan(Math.PI / 5.0)))); Ztemp2 /= 2.0; Vtemp[0].Set((float)(length / (2 * Math.Sin(Math.PI / 5))), 0.0f, (float)Ztemp2); for (int i = 1; i < 5; i++) { temp1.X = (float)(Vtemp[0].X * Math.Cos(2 * i * Math.PI / 5.0) - Vtemp[0].Y * Math.Sin(2 * i * Math.PI / 5.0)); temp1.Y = (float)(Vtemp[0].X * Math.Sin(2 * i * Math.PI / 5.0) + Vtemp[0].Y * Math.Cos(2 * i * Math.PI / 5.0)); Vtemp[i].Set(temp1.X, temp1.Y, (float)Ztemp2); } Vtemp[5].Set(0.0f, 0.0f, (float)(Ztemp1 + Ztemp2)); Vtemp[6].Set((float)(length / (2 * Math.Sin(Math.PI / 5))), 0.0f, -(float)Ztemp2); temp1.X = (float)(Vtemp[6].X * Math.Cos(Math.PI / 5.0) - Vtemp[6].Y * Math.Sin(Math.PI / 5.0)); temp1.Y = (float)(Vtemp[6].X * Math.Sin(Math.PI / 5.0) + Vtemp[6].Y * Math.Cos(Math.PI / 5.0)); Vtemp[6].Set(temp1.X, temp1.Y, -(float)Ztemp2); for (int i = 7; i < 11; i++) { temp1.X = (float)(Vtemp[6].X * Math.Cos(2 * (i - 6) * Math.PI / 5) - Vtemp[6].Y * Math.Sin(2 * (i - 6) * Math.PI / 5)); temp1.Y = (float)(Vtemp[6].X * Math.Sin(2 * (i - 6) * Math.PI / 5) + Vtemp[6].Y * Math.Cos(2 * (i - 6) * Math.PI / 5)); Vtemp[i].Set(temp1.X, temp1.Y, -(float)Ztemp2); } Vtemp[11].Set(0.0f, 0.0f, -(float)(Ztemp1 + Ztemp2)); Ptemp = new osPolygon(0); Ptemp.AddVertex(Vtemp[0]); Ptemp.AddVertex(Vtemp[1]); Ptemp.AddVertex(Vtemp[5]); Face3D.Add(Ptemp); Ptemp = new osPolygon(1); Ptemp.AddVertex(Vtemp[1]); Ptemp.AddVertex(Vtemp[2]); Ptemp.AddVertex(Vtemp[5]); Face3D.Add(Ptemp); Ptemp = new osPolygon(2); Ptemp.AddVertex(Vtemp[2]); Ptemp.AddVertex(Vtemp[3]); Ptemp.AddVertex(Vtemp[5]); Face3D.Add(Ptemp); Ptemp = new osPolygon(3); Ptemp.AddVertex(Vtemp[3]); Ptemp.AddVertex(Vtemp[4]); Ptemp.AddVertex(Vtemp[5]); Face3D.Add(Ptemp); Ptemp = new osPolygon(4); Ptemp.AddVertex(Vtemp[4]); Ptemp.AddVertex(Vtemp[0]); Ptemp.AddVertex(Vtemp[5]); Face3D.Add(Ptemp); Ptemp = new osPolygon(5); Ptemp.AddVertex(Vtemp[7]); Ptemp.AddVertex(Vtemp[6]); Ptemp.AddVertex(Vtemp[11]); Face3D.Add(Ptemp); Ptemp = new osPolygon(6); Ptemp.AddVertex(Vtemp[8]); Ptemp.AddVertex(Vtemp[7]); Ptemp.AddVertex(Vtemp[11]); Face3D.Add(Ptemp); Ptemp = new osPolygon(7); Ptemp.AddVertex(Vtemp[9]); Ptemp.AddVertex(Vtemp[8]); Ptemp.AddVertex(Vtemp[11]); Face3D.Add(Ptemp); Ptemp = new osPolygon(8); Ptemp.AddVertex(Vtemp[10]); Ptemp.AddVertex(Vtemp[9]); Ptemp.AddVertex(Vtemp[11]); Face3D.Add(Ptemp); Ptemp = new osPolygon(9); Ptemp.AddVertex(Vtemp[6]); Ptemp.AddVertex(Vtemp[10]); Ptemp.AddVertex(Vtemp[11]); Face3D.Add(Ptemp); Ptemp = new osPolygon(10); Ptemp.AddVertex(Vtemp[1]); Ptemp.AddVertex(Vtemp[0]); Ptemp.AddVertex(Vtemp[6]); Face3D.Add(Ptemp); Ptemp = new osPolygon(11); Ptemp.AddVertex(Vtemp[1]); Ptemp.AddVertex(Vtemp[6]); Ptemp.AddVertex(Vtemp[7]); Face3D.Add(Ptemp); Ptemp = new osPolygon(12); Ptemp.AddVertex(Vtemp[2]); Ptemp.AddVertex(Vtemp[1]); Ptemp.AddVertex(Vtemp[7]); Face3D.Add(Ptemp); Ptemp = new osPolygon(13); Ptemp.AddVertex(Vtemp[2]); Ptemp.AddVertex(Vtemp[7]); Ptemp.AddVertex(Vtemp[8]); Face3D.Add(Ptemp); Ptemp = new osPolygon(14); Ptemp.AddVertex(Vtemp[3]); Ptemp.AddVertex(Vtemp[2]); Ptemp.AddVertex(Vtemp[8]); Face3D.Add(Ptemp); Ptemp = new osPolygon(15); Ptemp.AddVertex(Vtemp[3]); Ptemp.AddVertex(Vtemp[8]); Ptemp.AddVertex(Vtemp[9]); Face3D.Add(Ptemp); Ptemp = new osPolygon(16); Ptemp.AddVertex(Vtemp[4]); Ptemp.AddVertex(Vtemp[3]); Ptemp.AddVertex(Vtemp[9]); Face3D.Add(Ptemp); Ptemp = new osPolygon(17); Ptemp.AddVertex(Vtemp[4]); Ptemp.AddVertex(Vtemp[9]); Ptemp.AddVertex(Vtemp[10]); Face3D.Add(Ptemp); Ptemp = new osPolygon(18); Ptemp.AddVertex(Vtemp[0]); Ptemp.AddVertex(Vtemp[4]); Ptemp.AddVertex(Vtemp[10]); Face3D.Add(Ptemp); Ptemp = new osPolygon(19); Ptemp.AddVertex(Vtemp[0]); Ptemp.AddVertex(Vtemp[10]); Ptemp.AddVertex(Vtemp[6]); Face3D.Add(Ptemp); List<Vector3D> temp = new List<Vector3D>(); for (int i = 0; i < Face3D.Count; i++) { Face3D[i].SetCenter(); temp.Add(Face3D[i].center); } for (int i = 0; i < temp.Count; i++) Dual.Add(new Vertex(temp[i].X, temp[i].Y, temp[i].Z)); Dual[0].SetNeighbor(Dual[1]); Dual[0].SetNeighbor(Dual[4]); Dual[0].SetNeighbor(Dual[10]); Dual[1].SetNeighbor(Dual[0]); Dual[1].SetNeighbor(Dual[2]); Dual[1].SetNeighbor(Dual[12]); Dual[2].SetNeighbor(Dual[1]); Dual[2].SetNeighbor(Dual[3]); Dual[2].SetNeighbor(Dual[14]); Dual[3].SetNeighbor(Dual[2]); Dual[3].SetNeighbor(Dual[4]); Dual[3].SetNeighbor(Dual[16]); Dual[4].SetNeighbor(Dual[3]); Dual[4].SetNeighbor(Dual[0]); Dual[4].SetNeighbor(Dual[18]); Dual[5].SetNeighbor(Dual[9]); Dual[5].SetNeighbor(Dual[6]); Dual[5].SetNeighbor(Dual[11]); Dual[6].SetNeighbor(Dual[5]); Dual[6].SetNeighbor(Dual[7]); Dual[6].SetNeighbor(Dual[13]); Dual[7].SetNeighbor(Dual[6]); Dual[7].SetNeighbor(Dual[8]); Dual[7].SetNeighbor(Dual[15]); Dual[8].SetNeighbor(Dual[7]); Dual[8].SetNeighbor(Dual[9]); Dual[8].SetNeighbor(Dual[17]); Dual[9].SetNeighbor(Dual[8]); Dual[9].SetNeighbor(Dual[5]); Dual[9].SetNeighbor(Dual[19]); Dual[10].SetNeighbor(Dual[0]); Dual[10].SetNeighbor(Dual[11]); Dual[10].SetNeighbor(Dual[19]); Dual[11].SetNeighbor(Dual[5]); Dual[11].SetNeighbor(Dual[10]); Dual[11].SetNeighbor(Dual[12]); Dual[12].SetNeighbor(Dual[1]); Dual[12].SetNeighbor(Dual[11]); Dual[12].SetNeighbor(Dual[13]); Dual[13].SetNeighbor(Dual[6]); Dual[13].SetNeighbor(Dual[12]); Dual[13].SetNeighbor(Dual[14]); Dual[14].SetNeighbor(Dual[2]); Dual[14].SetNeighbor(Dual[13]); Dual[14].SetNeighbor(Dual[15]); Dual[15].SetNeighbor(Dual[7]); Dual[15].SetNeighbor(Dual[14]); Dual[15].SetNeighbor(Dual[16]); Dual[16].SetNeighbor(Dual[3]); Dual[16].SetNeighbor(Dual[15]); Dual[16].SetNeighbor(Dual[17]); Dual[17].SetNeighbor(Dual[8]); Dual[17].SetNeighbor(Dual[16]); Dual[17].SetNeighbor(Dual[18]); Dual[18].SetNeighbor(Dual[4]); Dual[18].SetNeighbor(Dual[17]); Dual[18].SetNeighbor(Dual[19]); Dual[19].SetNeighbor(Dual[9]); Dual[19].SetNeighbor(Dual[18]); Dual[19].SetNeighbor(Dual[10]); }
public static float Inner(Vector3D A, Vector3D B) { return A.X * B.X + A.Y * B.Y + A.Z * B.Z; }
//辺edを回転軸として面をpolのある平面上に開く public bool Open(Edge ed, osPolygon pol) { if (!isOpened) { Vector3D edvector = new Vector3D(); double angle; Matrix rotatematrix = new Matrix(3); Vector3D polnormal; pol.SetNormal(); polnormal = pol.normal; SetNormal(); angle = Math.Acos(Vector3D.Inner(this.normal, polnormal) / (this.normal.Getnorm() * polnormal.Getnorm())); start_vertex = ed.vertex1; end_vertex = ed.vertex2; edvector = end_vertex.center3D - start_vertex.center3D; edvector.Normalization(); rotatematrix.Set_Rotate_ArbAx(edvector, angle); foreach (Vertex vtx in vertex) if (vtx.center3D != start_vertex.center3D && vtx.center3D != end_vertex.center3D) { vtx.center3D -= end_vertex.center3D; vtx.center3D = vtx.center3D * rotatematrix; vtx.center3D += end_vertex.center3D; } isOpened = true; return true; } return false; }
//外積 public static Vector3D Outer(Vector3D A, Vector3D B) { Vector3D P = new Vector3D(); P.X = A.Y * B.Z - A.Z * B.Y; P.Y = A.Z * B.X - A.X * B.Z; P.Z = A.X * B.Y - A.Y * B.X; return P; }
//隠面処理 public void HiddenRemoval(Vector3D see) { double cos; foreach (osPolygon pol in ViewFace3D) { cos = pol.Hidden(see); if (cos > 0) { pol.SetVisible(true); pol.nowbrush = new SolidBrush(Color.FromArgb((int)(pol.basebrush.Color.R * cos), (int)(pol.basebrush.Color.G * cos), (int)(pol.basebrush.Color.B * cos))); } else pol.SetVisible(false); } }
//頂点の挿入 public void Insert(int index, Vector3D coord) { vertex.Insert(index, new Vertex(coord.X, coord.Y, coord.Z)); vertices_num = vertex.Count; }
//カメラの回転 public void RotateCamera(double x1, double y1, double x2, double y2) { Vector2D A = new Vector2D(); Vector3D N1 = new Vector3D(); Vector3D N2 = new Vector3D(); Vector3D temp = new Vector3D(); double alpha, beta; float x, y, z; N1.X = Setposition.Y; N1.Y = -Setposition.X; N1.Z = LookatPoint.Z; N1.Normalization(); N2.X = LookatPoint.X; N2.Y = LookatPoint.Y; N2.Z = 1; N2.Normalization(); if (Upward.Z > 0) { A.X = (float)((x2 - x1) / w); A.Y = (float)((y2 - y1) / h); } if (Upward.Z < 0) { A.X = (float)((x1 - x2) / w); A.Y = (float)((y1 - y2) / h); } alpha = 2 * Math.PI * A.Y; beta = 2 * Math.PI * A.X; x = Setposition.X; y = Setposition.Y; z = Setposition.Z; rotatematrix.Set_Rotate_ArbAx(N1, alpha); temp = Setposition * rotatematrix; rotatematrix.Set_Rotate_ArbAx(N2, beta); temp = temp * rotatematrix; SetPosition(temp.X, temp.Y, temp.Z); if (Vector3D.Inner(temp2, Setposition - LookatPoint) > 0 && Upward.Z > 0) Upward.Z = -Upward.Z; if (Vector3D.Inner(temp2, Setposition - LookatPoint) < 0 && Upward.Z < 0) Upward.Z = -Upward.Z; if (Upward.Z > 0) temp2.Set(-Setposition.X, -Setposition.Y, LookatPoint.Z); if (Upward.Z < 0) temp2.Set(Setposition.X, Setposition.Y, LookatPoint.Z); }
//面の中心を設定 public void SetCenter() { center.Set(0, 0, 0); foreach (Vertex vtx in vertex) center += vtx.center3D; center = center / vertices_num; }
//座標軸より上か判定 public bool CheckIsUp() { Vector3D A = new Vector3D(0, 0, -1); return (Vector3D.Inner(A, -1 * Setposition) < 0); }
//頂点の設定 public void AddVertex(Vector3D coord) { vertex.Add(new Vertex(coord.X, coord.Y, coord.Z)); vertices_num = vertex.Count; }
//射影変換 public Vector3D ProjectionTranslate(Vector3D A) { Vector3D P = new Vector3D(); SetProjectionMatrix(); P = A * projectionmatrix; P.Z += (farZ * nearZ) / (farZ - nearZ); P.X = P.X / A.Z; P.Y = P.Y / A.Z; P.Z = P.Z / A.Z; return P; }