//コンストラクタ(引数あり) public Edge(Vertex vtx1, Vertex vtx2) { vertex1 = vtx1; vertex2 = vtx2; pen = new Pen(Color.Blue, 3); pen.DashStyle = DashStyle.Dot; neighbor = new List<Edge>(); isSeparated = false; willSeparated = false; viewOK = false; nealySeparated = false; }
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(); }
//辺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 void Set(Vertex vtx1, Vertex vtx2) { vertex1 = vtx1; vertex2 = vtx2; }
//双対頂点に一番近いEdgeを走査 private Edge SearchEdge(Vertex dualvertex1, Vertex dualvertex2, int faceindex) { int MinE = 0; float a1, a2; const int DISTANCE_UPPER = 10; for (int i = 0; i < Face3D[faceindex].edge.Count; i++) { a1 = dualvertex1.center3D.Getdistance((Face3D[faceindex].edge[i].vertex1.center3D + Face3D[faceindex].edge[i].vertex2.center3D) / 2); a2 = dualvertex2.center3D.Getdistance((Face3D[faceindex].edge[i].vertex1.center3D + Face3D[faceindex].edge[i].vertex2.center3D) / 2); if (Math.Abs(a1 - a2) < DISTANCE_UPPER) MinE = i; } return Face3D[faceindex].edge[MinE]; }
//一括座標変換(関数オーバロード) 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; }
//隣接面を回転 private bool RotateConnectFace(Vertex connectvtx, Vertex basevtx, Edge ed, int FaceNum) { int openindex; if (connectvtx.neighbor.Count == 1) { if ((openindex = GetDualNum(connectvtx)) != -1) { Face3D[openindex].CancelOpened(); Face3D[openindex].Open(ed, Face3D[FaceNum]); } return true; } else if (connectvtx.neighbor.Count > 1) { for (int i = 0; i < connectvtx.neighbor.Count; i++) { if (!Vector3D.NearlyEcoal(connectvtx.neighbor[i].center3D, basevtx.center3D, 10) && RotateConnectFace(connectvtx.neighbor[i], connectvtx, ed, FaceNum)) if ((openindex = GetDualNum(connectvtx)) != -1) { Face3D[openindex].CancelOpened(); Face3D[openindex].Open(ed, Face3D[FaceNum]); } } return true; } return false; }
//双対頂点番号を取得 private int GetDualNum(Vertex vtx) { for (int i = 0; i < Dual.Count; i++) { if (Vector3D.NearlyEcoal(Dual[i].center3D, vtx.center3D, 10)) return i; } return -1; }
//頂点の隣接点を追加 public void SetNeighbor(Vertex vtx) { neighbor.Add(vtx); nearlyNeighbor.Add(vtx); }
//隣接点を削除 public void DeleteNeighbor(Vertex vtx) { foreach (Vertex temp in neighbor) if (temp == vtx) { temp.Delete(this); break; } Delete(vtx); }
//ほとんど頂点を削除 public void DeleteNearly(Vertex vtx) { for (int i = 0; i < nearlyNeighbor.Count; i++) { if (vtx == nearlyNeighbor[i]) { nearlyNeighbor.RemoveAt(i); break; } } }