private void Walk(RL _dir, Frontier.FrontierPt _fPt) { var fvi = _fPt; var pts = D.Points; while (true) { var fvn = fvi[_dir]; var fLt = fvn[RL.Left]; var fRt = fvn[RL.Right]; var fvnPos = pts[fvn.VertIdx]; var vecL = pts[fLt.VertIdx] - fvnPos; var vecR = pts[fRt.VertIdx] - fvnPos; //var angleCW = vecL.AngleCW(vecR); //if (angleCW > Math.PI / 2f) break; //Positive Cross Product greater than 180 var crossZ = vecL.x * vecR.y - vecL.y * vecR.x; if (crossZ > 0) { break; } //Positive Dot product greater than 90 var dot = vecL.x * vecR.x + vecL.y * vecR.y; if (dot < 0) { break; } var twinLt = fLt.EdgeRight; var twinRt = fvn.EdgeRight; new Delaunay.Triangle(twinLt, twinRt, D); m_Frontier.Remove(fvn, twinLt.Twin.NextEdge); D.Legalize(twinLt, twinRt); } }
private void FillBasin(RL _dir, Frontier.FrontierPt _fpt) { //Setup var fvi = _fpt; var fvrp = fvi[_dir][_dir]; var polvi = m_PolPos[fvi.VertIdx]; var polvrp = m_PolPos[fvrp.VertIdx]; var pts = D.Points; var r2 = polvrp.r; var dr = polvi.r - r2; var dTheta = _dir == RL.Right ? polvrp.Theta - polvi.Theta : polvi.Theta - polvrp.Theta; //Check heuristic var h = dr / (r2 * dTheta); if (h < 2) { return; } //Find Basin Min var ptCount = 0; var fBasStart = fvrp; var fBasMin = fBasStart[_dir]; while (m_PolPos[fBasMin.VertIdx].r > m_PolPos[fBasMin[_dir].VertIdx].r) { fBasMin = fBasMin[_dir]; ptCount++; } if (ptCount == 0) { return; } //Find Basin End var fBasEnd = fBasMin; while (true) { var fbePos = pts[fBasEnd.VertIdx]; var vecL = pts[fBasEnd[RL.Left].VertIdx] - fbePos; var vecR = pts[fBasEnd[RL.Right].VertIdx] - fbePos; //Positive Cross Product greater than 180 var crossZ = vecL.x * vecR.y - vecL.y * vecR.x; if (crossZ > 0) { break; } fBasEnd = fBasEnd[_dir]; ptCount++; } if (fBasStart[_dir] == fBasEnd) { return; } //Sort Basin points by R var fBasScan = fBasStart[_dir]; m_BasinPtQ.Reset(ptCount); for (var sIdx = 0; sIdx < ptCount; ++sIdx) { m_BasinPtQ.Enqueue(fBasScan, m_PolPos[fBasScan.VertIdx].r); fBasScan = fBasScan[_dir]; } //Triangluate Basin while (m_BasinPtQ.Count != 0) { //Find frontier point that will be removed var fOut = m_BasinPtQ.Dequeue(); var fLt = fOut.Left; var fRt = fOut.Right; //Check that tri is valid (due to radius from Origin) var fOutPos = pts[fOut.VertIdx]; var vecL = pts[fLt.VertIdx] - fOutPos; var vecR = pts[fRt.VertIdx] - fOutPos; //Check for lines //Positive Cross Product greater than 180 var crossZ = vecL.x * vecR.y - vecL.y * vecR.x; if (crossZ >= 0) { break; } var twinLt = fOut[RL.Left].EdgeRight; var twinRt = fOut.EdgeRight; new Delaunay.Triangle(twinLt, twinRt, D); m_Frontier.Remove(fOut, twinLt.Twin.NextEdge); D.Legalize(twinLt, twinRt); } }