Exemplo n.º 1
0
        public void LloydRelax(Rect _trimBndy, int _iters = 1)
        {
            var progState  = "Voronoi Lloyd Relax";
            var prog       = 0f;
            var idxSiteCur = 0;
            var idxSiteTot = SitesByDIdx.Keys.Count;

            for (var iter = 0; iter < _iters; ++iter)
            {
                var centroids = new List <Vector2>();
                foreach (var siteIdx in SitesByDIdx.Keys)
                {
                    prog      = (float)idxSiteCur++ / idxSiteTot;
                    progState = "Voronoi Lloyd Relax " + idxSiteCur + " of " + idxSiteTot;
                    D.Prog.Update(prog, progState);

                    var site     = SitesByDIdx[siteIdx];
                    var centroid = Geom.CentroidOfPoly(site.Edges.Select(_edge => _edge.Origin));
                    centroids.Add(centroid);
                }

                D.Triangulate(centroids.ToArray());
                Build();
                TrimSitesToBndry(_trimBndy);
            }
        }
Exemplo n.º 2
0
        private Vector2 CalcOriginOrig(out int[] _firstTriIdxs)
        {
            var cent    = D.BoundsRect.center;
            var closest = new SortedList <float, int>
            {
                { (cent - D.Points[0]).sqrMagnitude, 0 },
                { (cent - D.Points[1]).sqrMagnitude, 1 },
                { (cent - D.Points[2]).sqrMagnitude, 2 }
            };

            for (var idx = 3; idx < D.Points.Length; ++idx)
            {
                var pt      = D.Points[idx];
                var distSqr = (cent - pt).sqrMagnitude;
                if (distSqr > closest.Keys[2])
                {
                    continue;
                }
                closest.Add(distSqr, idx);
            }

            _firstTriIdxs = new[] { closest.Values[0], closest.Values[1], closest.Values[2] };
            //Find 1st non-linear set of points (valid triangle)
            var findNonLineIdx = 3;

            while (Geom.AreColinear(D.Points[_firstTriIdxs[0]], D.Points[_firstTriIdxs[1]], D.Points[_firstTriIdxs[2]],
                                    D.MinFloatingPointErr))
            {
                _firstTriIdxs[2] = closest.Values[findNonLineIdx++];
            }

            //Force Clockwise
            var v0   = D.Points[_firstTriIdxs[0]];
            var v1   = D.Points[_firstTriIdxs[1]];
            var v2   = D.Points[_firstTriIdxs[2]];
            var vecL = v1 - v0;
            var vecR = v2 - v0;

            //Positive Cross Product greater than 180
            var crossZ = vecL.x * vecR.y - vecL.y * vecR.x;

            if (crossZ > 0)
            {
                var tempIdx = _firstTriIdxs[1];
                _firstTriIdxs[1] = _firstTriIdxs[2];
                _firstTriIdxs[2] = tempIdx;
            }

            var triPts = new[] { D.Points[_firstTriIdxs[0]], D.Points[_firstTriIdxs[1]], D.Points[_firstTriIdxs[2]] };
            var cc     = Geom.CentroidOfPoly(triPts);

            return(cc);
        }
Exemplo n.º 3
0
                private void ComputeSiteData()
                {
                    var progress = new Progress("Computing Site Data");

                    progress.SetOnUpdate(ProgOnUpdate);
                    var triScan = Delaunay.LastTri;

                    TMesh.SiteCorners       = new int[TriangleCount][];
                    TMesh.SiteNeighbors     = new int[TriangleCount][];
                    TMesh.SitesHavingCorner = new HashSet <int> [TMesh.Vertices.Length];
                    progress.Update(0, "Filling Neighbors");
                    while (triScan != null)
                    {
                        var tIdx        = TriangleIndexReference[triScan];
                        var triVertPoss = new[]
                        {
                            triScan.Edge0.OriginPos,
                            triScan.Edge1.OriginPos,
                            triScan.Edge2.OriginPos
                        };
                        var tCent = Geom.CentroidOfPoly(triVertPoss); //Use centroid instead of CircCent
                        TMesh.SiteCorners[tIdx]   = new int[3];
                        TMesh.SiteNeighbors[tIdx] = new int[3];
                        //Record neighbors
                        var edges = new[] { triScan.Edge0, triScan.Edge1, triScan.Edge2 };
                        for (var eIdx = 0; eIdx < 3; ++eIdx)
                        {
                            var edge = edges[eIdx];
                            var oIdx = edge.OriginIdx;
                            if (TMesh.SitesHavingCorner[oIdx] == null)
                            {
                                TMesh.SitesHavingCorner[oIdx] = new HashSet <int>();
                            }
                            TMesh.SitesHavingCorner[oIdx].Add(tIdx);
                            TMesh.SiteCorners[tIdx][eIdx] = oIdx;

                            if (edge.Twin != null)
                            {
                                TMesh.SiteNeighbors[tIdx][eIdx] = TriangleIndexReference[edge.Twin.Triangle];
                            }
                            else
                            {
                                TMesh.SiteNeighbors[tIdx][eIdx] = SiteIdxNull;
                            }
                        }

                        triScan = triScan.PrevTri;
                        progress.Update((float)TriangleCount / TMesh.Triangles.Length);
                    }
                }
Exemplo n.º 4
0
        private Vector2 CalcOrigin(out int[] _firstTriIdxs)
        {
            var cent     = D.BoundsRect.center;
            var pIdxArr  = new int[D.Points.Length];
            var pDistArr = new float[D.Points.Length];

            for (var idx = 0; idx < pIdxArr.Length; ++idx)
            {
                var dx = Math.Abs(cent.x - D.Points[idx].x);
                var dy = Math.Abs(cent.y - D.Points[idx].y);
                pIdxArr[idx]  = idx;
                pDistArr[idx] = dx + dy;
            }

            Array.Sort(pIdxArr, (_a, _b) => pDistArr[_a].CompareTo(pDistArr[_b]));

            _firstTriIdxs = new[] { pIdxArr[0], pIdxArr[1], pIdxArr[2] };
            //Find 1st non-linear set of points (valid triangle)
            var findNonLineIdx = 3;

            while (Geom.AreColinear(D.Points[_firstTriIdxs[0]], D.Points[_firstTriIdxs[1]], D.Points[_firstTriIdxs[2]],
                                    D.MinFloatingPointErr))
            {
                _firstTriIdxs[2] = pIdxArr[findNonLineIdx++];
            }

            //Force Clockwise
            var v0   = D.Points[_firstTriIdxs[0]];
            var v1   = D.Points[_firstTriIdxs[1]];
            var v2   = D.Points[_firstTriIdxs[2]];
            var vecL = v1 - v0;
            var vecR = v2 - v0;

            //Positive Cross Product greater than 180
            var crossZ = vecL.x * vecR.y - vecL.y * vecR.x;

            if (crossZ > 0)
            {
                var tempIdx = _firstTriIdxs[1];
                _firstTriIdxs[1] = _firstTriIdxs[2];
                _firstTriIdxs[2] = tempIdx;
            }

            var triPts = new[] { D.Points[_firstTriIdxs[0]], D.Points[_firstTriIdxs[1]], D.Points[_firstTriIdxs[2]] };
            var cc     = Geom.CentroidOfPoly(triPts);

            return(cc);
        }
Exemplo n.º 5
0
        private Vector2 CalcOrigin2(out int[] _firstTriIdxs)
        {
            var cent = D.BoundsRect.center;
            Func <Vector2, float> fPtDist = _p => Math.Abs(_p.x) + Math.Abs(_p.y);

            var lstPIdx = new List <int>(3)
            {
                0, 1, 2
            };
            var lstPDist = new List <float>(3)
            {
                fPtDist(D.Points[0]), fPtDist(D.Points[1]), fPtDist(D.Points[2])
            };

            lstPIdx.Sort((_a, _b) => lstPDist[_a].CompareTo(lstPDist[_b]));
            lstPDist = new List <float>(3)
            {
                fPtDist(D.Points[lstPIdx[0]]),
                fPtDist(D.Points[lstPIdx[1]]),
                fPtDist(D.Points[lstPIdx[2]])
            };

            for (var pIdx = 3; pIdx < D.Points.Length; ++pIdx)
            {
                var pDist = fPtDist(D.Points[pIdx]);
                if (pDist > lstPDist[2])
                {
                    continue;
                }
                if (pDist < lstPDist[0])
                {
                    lstPDist[2] = lstPDist[1];
                    lstPIdx[2]  = lstPIdx[1];
                    lstPDist[1] = lstPDist[0];
                    lstPIdx[1]  = lstPIdx[0];
                    lstPDist[0] = pDist;
                    lstPIdx[0]  = pIdx;
                    continue;
                }

                if (pDist < lstPDist[1])
                {
                    lstPDist[2] = lstPDist[1];
                    lstPIdx[2]  = lstPIdx[1];
                    lstPDist[1] = pDist;
                    lstPIdx[1]  = pIdx;
                    continue;
                }

                lstPDist[2] = pDist;
                lstPIdx[2]  = pIdx;
            }


            _firstTriIdxs = lstPIdx.ToArray();
            //Find 1st non-linear set of points (valid triangle)
            var findNonLineIdx = 3;

            while (Geom.AreColinear(D.Points[_firstTriIdxs[0]], D.Points[_firstTriIdxs[1]], D.Points[_firstTriIdxs[2]],
                                    D.MinFloatingPointErr))
            {
                var dIdx   = _firstTriIdxs[0];
                var dbgPt0 = D.Points[_firstTriIdxs[0]]; //TODO remove
                var dbgPt1 = D.Points[_firstTriIdxs[1]];
                var dbgPt2 = D.Points[_firstTriIdxs[2]];

                var mPntX  = D.Points[dIdx].x;
                var mPntY  = D.Points[dIdx].y;
                var rnd    = new Random((int)DateTime.Now.Ticks);
                var rndDir = rnd.Next(4);
                if (rndDir == 0)
                {
                    D.Points[dIdx].Set(mPntX + D.MinFloatingPointErr, mPntY);
                }
                else if (rndDir == 1)
                {
                    D.Points[dIdx].Set(mPntX - D.MinFloatingPointErr, mPntY);
                }
                else if (rndDir == 2)
                {
                    D.Points[dIdx].Set(mPntX, mPntY + D.MinFloatingPointErr);
                }
                else
                {
                    D.Points[dIdx].Set(mPntX, mPntY - D.MinFloatingPointErr);
                }
            }

            ;

            //Force Clockwise
            var v0   = D.Points[_firstTriIdxs[0]];
            var v1   = D.Points[_firstTriIdxs[1]];
            var v2   = D.Points[_firstTriIdxs[2]];
            var vecL = v1 - v0;
            var vecR = v2 - v0;

            //Positive Cross Product greater than 180
            var crossZ = vecL.x * vecR.y - vecL.y * vecR.x;

            if (crossZ > 0)
            {
                var tempIdx = _firstTriIdxs[1];
                _firstTriIdxs[1] = _firstTriIdxs[2];
                _firstTriIdxs[2] = tempIdx;
            }

            var triPts = new[] { D.Points[_firstTriIdxs[0]], D.Points[_firstTriIdxs[1]], D.Points[_firstTriIdxs[2]] };
            var cc     = Geom.CentroidOfPoly(triPts);

            return(cc);
        }
Exemplo n.º 6
0
 private Vector3 GetSitePosition(int _siteIdx)
 {
     return(Geom.CentroidOfPoly(GetCornersOfSite(_siteIdx)));
 }