コード例 #1
0
ファイル: CircleSweep.cs プロジェクト: phildo77/ioDelaunay
        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);
            }
        }
コード例 #2
0
ファイル: CircleSweep.cs プロジェクト: phildo77/ioDelaunay
        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);
            }
        }