override public void ComputeKeys() { double eps = 0.001; double eps2 = eps * eps; int ib = 0; int ie = this.NumOfPoints - 1; SHomog line = new SHomog(Points[ib], Points[ie]); double lensq = Points[ib].SqrDist(Points[ie]); if (lensq < eps2) { throw new Exception("start and end points are too close"); } //ie--; AddBuildStep(null, null, ib, ie, eBuildStep.Build); Build(); //AddBuildStep(ib, ib, eBuildStep.OutputVertex); AddBuildStep(null, null, ib, ib, eBuildStep.ReturnKey); ReturnKey(); //AddBuildStep(null, null, 0, 0, eBuildStep.OutputVertex); //OutputVertex(); //AddBuildStep(null, null, 0, 0, eBuildStep.OutputVertex); //AddBuildStep(ib, ib, eBuildStep.OutputVertex); AddBuildStep(null, null, ib, ie, eBuildStep.DP); while (m_stack.Count() > 0) { switch (m_stack.First().eBuild) { case eBuildStep.DP: DP(); break; case eBuildStep.Build: Build(); break; case eBuildStep.ReturnKey: ReturnKey(); break; case eBuildStep.OutputVertex: //OutputVertex(); Debug.Assert(false); break; case eBuildStep.UpdateHull: UpdateHull(); break; default: Debug.Assert(false); break; } } }
private void DP() { double rd = 0, ld = 0, lensq = 0; int re = 0, le = 0; Debug.Assert(m_stack.Count() > 0); Debug.Assert(m_stack.First().eBuild == eBuildStep.DP); int ib = m_stack.First().iB; int ie = m_stack.First().iE; m_stack.Pop(); SHomog line = new SHomog(Points[ib], Points[ie]); lensq = Points[ib].SqrDist(Points[ie]); if ((ie - ib) < 2) { AddBuildStep(null, null, ie, ie, eBuildStep.ReturnKey); return; } this.m_LHull.Find_Extreme(line, ref le, ref ld); this.m_RHull.Find_Extreme(line, ref re, ref rd); if (ld > rd) { if (ld * ld > Tol * lensq) { PathHullStack lh = m_LHull.Copy(); PathHullStack rh = m_RHull.Copy(); lh.Split(le); //AddBuildStep(null, null, 0, 0, eBuildStep.OutputVertex); AddBuildStep(null, null, le, ie, eBuildStep.DP); AddBuildStep(lh, rh, m_PHTag, 0, eBuildStep.UpdateHull); AddBuildStep(null, null, ib, le, eBuildStep.DP); AddBuildStep(null, null, ib, le, eBuildStep.Build); //AddBuildStep(null, null, le, ie, eBuildStep.DP); return; } else { AddBuildStep(null, null, ie, ie, eBuildStep.ReturnKey); return; } } else { if (rd * rd > Tol * lensq) { if (m_PHTag != re) { m_RHull.Split(re); } AddBuildStep(null, null, re, ie, eBuildStep.DP); AddBuildStep(null, null, re, ie, eBuildStep.Build); // AddBuildStep(null, null,0, 0, eBuildStep.OutputVertex); AddBuildStep(null, null, ib, re, eBuildStep.DP); if (m_PHTag == re) { AddBuildStep(null, null, ib, re, eBuildStep.Build); } return; } else { AddBuildStep(null, null, ie, ie, eBuildStep.ReturnKey); } } //if ((ie - ib) < 8) { // rd = 0; // for (int i = ib + 1; i < ie; i++) { // ld = Math.Abs(line.DotProduct_2CH(Points[i])); // if (ld > rd) { // rd = ld; // re = i; // } // } // if (rd * rd > Tol * lensq) { // AddBuildStep(re, ie, eBuildStep.DP); // AddBuildStep(ib, re, eBuildStep.OutputVertex); // AddBuildStep(ib, re, eBuildStep.DP); // return; // } else { // AddBuildStep(ie, ie, eBuildStep.ReturnKey); // return; // } //} else { //} }
public void Find_Extreme(SHomog line, ref int ie, ref double dist) { int mid, lo, m1, brk, m2, hi; bool sbase, sbrk; double d1, d2; if ((Top - Bot) > 6) { lo = Bot; hi = Top - 1; sbase = line.Slope_Sign(Pts[Elt[hi]], Pts[Elt[lo]]); do { brk = (lo + hi) / 2; sbrk = line.Slope_Sign(Pts[Elt[brk]], Pts[Elt[brk + 1]]); if (sbase == sbrk) { if (sbase == line.Slope_Sign(Pts[Elt[lo]], Pts[Elt[brk + 1]])) { lo = brk + 1; } else { hi = brk; } } } while (sbase == sbrk); m1 = brk; while (lo < m1) { mid = (lo + m1) / 2; if (sbase == line.Slope_Sign(Pts[Elt[mid]], Pts[Elt[mid + 1]])) { lo = mid + 1; } else { m1 = mid; } } m2 = brk; while (m2 < hi) { mid = (m2 + hi) / 2; if (sbase == line.Slope_Sign(Pts[Elt[mid]], Pts[Elt[mid + 1]])) { hi = mid; } else { m2 = mid + 1; } } d1 = Math.Abs(line.DotProduct_2CH(Pts[Elt[lo]])); d2 = Math.Abs(line.DotProduct_2CH(Pts[Elt[m2]])); if (d1 > d2) { dist = d1; ie = Elt[lo]; } else { dist = d2; ie = Elt[m2]; } } else { dist = 0; for (mid = Bot; mid < Top; mid++) { d1 = Math.Abs(line.DotProduct_2CH(Pts[Elt[mid]])); if (d1 > dist) { dist = d1; ie = Elt[mid]; } } } }