private void MainLoop() { int count = 0; while (faceQueue.Count > 0) { count++; HullFace face = faceQueue.Dequeue(); if (face.active == false) { continue; } if (face.furthestIndex != -1) { int p0 = face.furthestIndex; this.hullVertices.Add(p0); // collect visible faces, boundary edges and assoicated vertices List <HullFace> holeFace = new List <HullFace>(); HashSet <EdgeRecord> holeBoundary = new HashSet <EdgeRecord>(); HashSet <int> assoicatedVertex = new HashSet <int>(); foreach (HullFace f in this.surfaceSet) { Vector3d v = this.p[p0] - this.p[f.p1]; if (v.Dot(f.normal) > 0) { holeFace.Add(f); int p1 = f.p1; int p2 = f.p2; int p3 = f.p3; EdgeRecord r1 = new EdgeRecord(p1, p2); EdgeRecord r2 = new EdgeRecord(p2, p3); EdgeRecord r3 = new EdgeRecord(p3, p1); if (holeBoundary.Contains(r1)) { holeBoundary.Remove(r1); } else { holeBoundary.Add(r1); } if (holeBoundary.Contains(r2)) { holeBoundary.Remove(r2); } else { holeBoundary.Add(r2); } if (holeBoundary.Contains(r3)) { holeBoundary.Remove(r3); } else { holeBoundary.Add(r3); } foreach (int index in f.associatedPoints) { assoicatedVertex.Add(index); } } } if (holeFace.Count == 0) { throw new Exception(); } // remove add visible faces foreach (HullFace f in holeFace) { this.surfaceSet.Remove(f); f.active = false; } // add new faces foreach (EdgeRecord edge in holeBoundary) { HullFace newFace = new HullFace(p0, edge.p1, edge.p2); newFace.normal = ((p[edge.p1] - p[p0]).Cross(p[edge.p2] - p[p0])).normalize(); this.surfaceSet.Add(newFace); this.faceQueue.Enqueue(newFace); // add assoicated vertices foreach (int index in assoicatedVertex) { if (index == p0) { continue; } double dis = (p[index] - p[p0]).Dot(newFace.normal); if (dis > 0) { newFace.AddPoint(index, dis); } } } } } computeCenter(); }
private void InitHullFaces() { // get init points int[] initPts = FindInitPoints(); this.initIndex = initPts; int p0 = initPts[0]; int p1 = initPts[1]; int p2 = initPts[2]; int p3 = initPts[3]; double vol = (p[p1] - p[p0]).Dot((p[p2] - p[p0]).Cross(p[p3] - p[p0])); if (vol > 0) { int t = p0; p0 = p1; p1 = t; } this.hullVertices.Add(p0); this.hullVertices.Add(p1); this.hullVertices.Add(p2); this.hullVertices.Add(p3); // create hull faces HullFace f1 = new HullFace(p0, p1, p2); this.faceQueue.Enqueue(f1); HullFace f2 = new HullFace(p3, p1, p0); this.faceQueue.Enqueue(f2); HullFace f3 = new HullFace(p3, p2, p1); this.faceQueue.Enqueue(f3); HullFace f4 = new HullFace(p3, p0, p2); this.faceQueue.Enqueue(f4); f1.normal = ((p[p1] - p[p0]).Cross(p[p2] - p[p0])).normalize(); f2.normal = ((p[p1] - p[p3]).Cross(p[p0] - p[p3])).normalize(); f3.normal = ((p[p2] - p[p3]).Cross(p[p1] - p[p3])).normalize(); f4.normal = ((p[p0] - p[p3]).Cross(p[p2] - p[p3])).normalize(); this.surfaceSet.Add(f1); this.surfaceSet.Add(f2); this.surfaceSet.Add(f3); this.surfaceSet.Add(f4); // assoicate vertices outside current hull foreach (int i in this.pointIndex) { if (i == p0 || i == p1 || i == p2 || i == p3) { continue; } double d1 = (p[i] - p[p0]).Dot(f1.normal); double d2 = (p[i] - p[p3]).Dot(f2.normal); double d3 = (p[i] - p[p3]).Dot(f3.normal); double d4 = (p[i] - p[p3]).Dot(f4.normal); if (d1 < 0 && d2 < 0 && d3 < 0 && d4 < 0) { continue; } if (d1 > 0) { f1.AddPoint(i, d1); } if (d2 > 0) { f2.AddPoint(i, d2); } if (d3 > 0) { f3.AddPoint(i, d3); } if (d4 > 0) { f4.AddPoint(i, d4); } } }