Vector3D[] vertex3D; //3次元上の頂点集合 #endregion Fields #region Constructors //コンストラクタ(引数:1辺の長さ) public Square(float length) { center = new Vector3D(0.0f, 0.0f, 0.0f); vertex3D = new Vector3D[VERTICES_NUM]; vertex2D = new Vector2D[VERTICES_NUM]; this.length = length; for (int i = 0; i < VERTICES_NUM; i++) { vertex2D[i] = new Vector2D(); vertex3D[i] = new Vector3D(); } brush = new SolidBrush(Color.FromArgb(255, 211, 225)); vertex3D[0].X = length / 2 + center.X; vertex3D[0].Y = length / 2 + center.Y; vertex3D[0].Z = center.Z; vertex3D[1].X = -length / 2 + center.X; vertex3D[1].Y = length / 2 + center.Y; vertex3D[1].Z = center.Z; vertex3D[2].X = -length / 2 + center.X; vertex3D[2].Y = -length / 2 + center.Y; vertex3D[2].Z = center.Z; vertex3D[3].X = length / 2 + center.X; vertex3D[3].Y = -length / 2 + center.Y; vertex3D[3].Z = center.Z; }
//Vector2DをPointF[]に変換 public static PointF[] ToPointF(Vector2D[] A) { PointF[] P = new PointF[A.Length]; for (int i = 0; i < A.Length; i++) { P[i] = A[i].ToPointF(); } return P; }
float MinY; //Y座標の最小値 #endregion Fields #region Constructors //コンストラクタ public Grid3D() { grid3D = new List<Vector3D>(); grid2D = new List<Vector2D>(); Axis3D = new Vector3D[4]; Axis2D = new Vector2D[4]; for (int i = 0; i < 4; i++) { Axis3D[i] = new Vector3D(); Axis2D[i] = new Vector2D(); } MaxX = 40.0f; MinX = -40.0f; MaxY = 40.0f; MinY = -40.0f; Xunit = 2.0f; Yunit = 2.0f; GridPen = new Pen(Color.Blue); GridPen.DashStyle = DashStyle.Dot; AxisPen = new Pen(Color.Blue); }
//2つのベクトルの距離を取得 public float Getdistance(Vector2D A) { return (A - this).Getnorm(); }
public static float Inner(Vector2D A, Vector2D B) { return A.X * B.X + A.Y * B.Y; }
//座標を設定 public Vector2D(Vector2D v) { this.Set(v.X, v.Y); }
//3次元上の座標を作成 public void CreateGrid3D(Camera c) { Vector3D tempX = new Vector3D(); Vector3D tempY = new Vector3D(); Vector3D Grid3D1 = new Vector3D(); Vector3D Grid3D2 = new Vector3D(); Vector2D Grid2D1 = new Vector2D(); Vector2D Grid2D2 = new Vector2D(); grid3D.Clear(); grid2D.Clear(); for (float i = -Xunit; i > MinY; i -= Xunit) { Grid3D1.Set(i, MaxY, 0.0f); grid3D.Add(new Vector3D(Grid3D1)); Grid3D2.Set(i, MinY, 0.0f); grid3D.Add(new Vector3D(Grid3D2)); tempX = c.ViewTranslate(Grid3D1); tempX = c.ProjectionTranslate(tempX); Grid2D1 = c.ViewPortTranslate(tempX); grid2D.Add(new Vector2D(Grid2D1)); tempY = c.ViewTranslate(Grid3D2); tempY = c.ProjectionTranslate(tempY); Grid2D2 = c.ViewPortTranslate(tempY); grid2D.Add(new Vector2D(Grid2D2)); } for (float i = Xunit; i < MaxX; i += Xunit) { Grid3D1.Set(i, MaxY, 0.0f); grid3D.Add(new Vector3D(Grid3D1)); Grid3D2.Set(i, MinY, 0.0f); grid3D.Add(new Vector3D(Grid3D2)); tempX = c.ViewTranslate(Grid3D1); tempX = c.ProjectionTranslate(tempX); Grid2D1 = c.ViewPortTranslate(tempX); grid2D.Add(new Vector2D(Grid2D1)); tempY = c.ViewTranslate(Grid3D2); tempY = c.ProjectionTranslate(tempY); Grid2D2 = c.ViewPortTranslate(tempY); grid2D.Add(new Vector2D(Grid2D2)); } for (float i = -Yunit; i > MinY; i -= Yunit) { Grid3D1.Set(MaxX, i, 0.0f); grid3D.Add(new Vector3D(Grid3D1)); Grid3D2.Set(MinX, i, 0.0f); grid3D.Add(new Vector3D(Grid3D2)); tempX = c.ViewTranslate(Grid3D1); tempX = c.ProjectionTranslate(tempX); Grid2D1 = c.ViewPortTranslate(tempX); grid2D.Add(new Vector2D(Grid2D1)); tempY = c.ViewTranslate(Grid3D2); tempY = c.ProjectionTranslate(tempY); Grid2D2 = c.ViewPortTranslate(tempY); grid2D.Add(new Vector2D(Grid2D2)); } for (float i = Yunit; i < MaxY; i += Yunit) { Grid3D1.Set(MaxX, i, 0.0f); grid3D.Add(new Vector3D(Grid3D1)); Grid3D2.Set(MinX, i, 0.0f); grid3D.Add(new Vector3D(Grid3D2)); tempX = c.ViewTranslate(Grid3D1); tempX = c.ProjectionTranslate(tempX); Grid2D1 = c.ViewPortTranslate(tempX); grid2D.Add(new Vector2D(Grid2D1)); tempY = c.ViewTranslate(Grid3D2); tempY = c.ProjectionTranslate(tempY); Grid2D2 = c.ViewPortTranslate(tempY); grid2D.Add(new Vector2D(Grid2D2)); } Grid3D1.Set(MaxX, 0.0f, 0.0f); Axis3D[0] = new Vector3D(Grid3D1); Grid3D2.Set(MinX, 0.0f, 0.0f); Axis3D[1] = new Vector3D(Grid3D2); tempX = c.ViewTranslate(Grid3D1); tempX = c.ProjectionTranslate(tempX); Grid2D1 = c.ViewPortTranslate(tempX); Axis2D[0] = new Vector2D(Grid2D1); tempY = c.ViewTranslate(Grid3D2); tempY = c.ProjectionTranslate(tempY); Grid2D2 = c.ViewPortTranslate(tempY); Axis2D[1] = new Vector2D(Grid2D2); Grid3D1.Set(0.0f, MaxY, 0.0f); Axis3D[2] = new Vector3D(Grid3D1); Grid3D2.Set(0.0f, MinY, 0.0f); Axis3D[3] = new Vector3D(Grid3D2); tempX = c.ViewTranslate(Grid3D1); tempX = c.ProjectionTranslate(tempX); Grid2D1 = c.ViewPortTranslate(tempX); Axis2D[2] = new Vector2D(Grid2D1); tempY = c.ViewTranslate(Grid3D2); tempY = c.ProjectionTranslate(tempY); Grid2D2 = c.ViewPortTranslate(tempY); Axis2D[3] = new Vector2D(Grid2D2); }
//コンストラクタ(引数:1辺の長さ, brush) public Cube(float len, SolidBrush c) { center = new Vector3D(0.0f, 0.0f, 0.0f); vertex3D = new Vector3D[VERTICES_NUM]; vertex2D = new Vector2D[VERTICES_NUM]; face3D = new Vector3D[FACES_NUM][]; face2D = new Vector2D[FACES_NUM][]; canSee = new bool[FACES_NUM]; length = len; for (int i = 0; i < VERTICES_NUM; i++) { vertex2D[i] = new Vector2D(); vertex3D[i] = new Vector3D(); } for (int i = 0; i < FACES_NUM; i++) { face2D[i] = new Vector2D[4]; face3D[i] = new Vector3D[4]; } for (int i = 0; i < FACES_NUM; i++) { for (int j = 0; j < 4; j++) { face2D[i][j] = new Vector2D(); face3D[i][j] = new Vector3D(); } } brush = new SolidBrush[FACES_NUM]; basebrush = new SolidBrush[FACES_NUM]; for (int i = 0; i < basebrush.Length; i++) basebrush[i] = c; vertex3D[0].X = length / 2 + center.X; vertex3D[0].Y = length / 2 + center.Y; vertex3D[0].Z = length / 2 + center.Z; vertex3D[1].X = -length / 2 + center.X; vertex3D[1].Y = length / 2 + center.Y; vertex3D[1].Z = length / 2 + center.Z; vertex3D[2].X = -length / 2 + center.X; vertex3D[2].Y = -length / 2 + center.Y; vertex3D[2].Z = length / 2 + center.Z; vertex3D[3].X = length / 2 + center.X; vertex3D[3].Y = -length / 2 + center.Y; vertex3D[3].Z = length / 2 + center.Z; vertex3D[4].X = length / 2 + center.X; vertex3D[4].Y = length / 2 + center.Y; vertex3D[4].Z = -length / 2 + center.Z; vertex3D[5].X = -length / 2 + center.X; vertex3D[5].Y = length / 2 + center.Y; vertex3D[5].Z = -length / 2 + center.Z; vertex3D[6].X = -length / 2 + center.X; vertex3D[6].Y = -length / 2 + center.Y; vertex3D[6].Z = -length / 2 + center.Z; vertex3D[7].X = length / 2 + center.X; vertex3D[7].Y = -length / 2 + center.Y; vertex3D[7].Z = -length / 2 + center.Z; SetFace3D(); }
//ビューポート変換 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 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 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); }