Ejemplo n.º 1
0
        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="items"></param>
        /// <param name="getPosition"></param>
        /// <param name="grid"></param>
        /// <param name="indexMap"></param>
        /// <param name="tolerance"></param>
        /// <returns></returns>
        public static List <T> RemoveCoincident <T>(IReadOnlyList <T> items, Func <T, Vec2d> getPosition, HashGrid2d <int> grid, out int[] indexMap, double tolerance = SlurMath.ZeroTolerance)
        {
            var result = new List <T>();
            var map    = new int[items.Count];

            grid.Scale = tolerance * RadiusToHashScale;

            // add points to result if no duplicates are found
            for (int i = 0; i < items.Count; i++)
            {
                var p0 = getPosition(items[i]);

                // search for concident in result
                foreach (int j in grid.Search(new Interval2d(p0, tolerance)))
                {
                    if (p0.ApproxEquals(getPosition(result[j]), tolerance))
                    {
                        map[i] = j;
                        goto EndFor;
                    }
                }

                // no coincident item found, add i to result
                grid.Insert(p0, result.Count);
                map[i] = result.Count;
                result.Add(items[i]);

                EndFor :;
            }

            indexMap = map;
            return(result);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// For each item in A, returns the index of the first coincident item in B. If no coincident point is found, -1 is returned.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="U"></typeparam>
        /// <param name="itemsA"></param>
        /// <param name="getPositionA"></param>
        /// <param name="itemsB"></param>
        /// <param name="getPositionB"></param>
        /// <param name="grid"></param>
        /// <param name="tolerance"></param>
        /// <returns></returns>
        public static IEnumerable <int> GetFirstCoincident <T, U>(IReadOnlyList <T> itemsA, Func <T, Vec2d> getPositionA, IReadOnlyList <U> itemsB, Func <U, Vec2d> getPositionB, HashGrid2d <int> grid, double tolerance = SlurMath.ZeroTolerance)
        {
            grid.Scale = tolerance * RadiusToHashScale;

            // insert B
            for (int i = 0; i < itemsB.Count; i++)
            {
                grid.Insert(getPositionB(itemsB[i]), i);
            }

            // search from A
            for (int i = 0; i < itemsA.Count; i++)
            {
                var p0 = getPositionA(itemsA[i]);

                foreach (var j in grid.Search(new Interval3d(p0, tolerance)))
                {
                    if (p0.ApproxEquals(getPositionB(itemsB[j]), tolerance))
                    {
                        yield return(j);

                        goto EndFor;
                    }
                }

                yield return(-1);

                EndFor :;
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// For each item, returns the index of the first coincident item within the same list. If no coincident point is found, -1 is returned.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="items"></param>
        /// <param name="grid"></param>
        /// <param name="getPosition"></param>
        /// <param name="tolerance"></param>
        /// <returns></returns>
        public static IEnumerable <int> GetFirstCoincident <T>(IReadOnlyList <T> items, Func <T, Vec2d> getPosition, HashGrid2d <int> grid, double tolerance = 1.0e-8)
        {
            grid.BinScale = tolerance * RadiusToBinScale;

            // insert
            for (int i = 0; i < items.Count; i++)
            {
                grid.Insert(getPosition(items[i]), i);
            }

            // search
            for (int i = 0; i < items.Count; i++)
            {
                var p0 = getPosition(items[i]);

                foreach (var j in grid.Search(new Interval2d(p0, tolerance)))
                {
                    if (i != j && p0.ApproxEquals(getPosition(items[j]), tolerance))
                    {
                        yield return(j);

                        goto EndFor;
                    }
                }

                yield return(-1);

                EndFor :;
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// For each item in A, returns the index of each coincident items in B.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="U"></typeparam>
        /// <param name="itemsA"></param>
        /// <param name="getPositionA"></param>
        /// <param name="itemsB"></param>
        /// <param name="getPositionB"></param>
        /// <param name="grid"></param>
        /// <param name="tolerance"></param>
        /// <returns></returns>
        public static IEnumerable <IEnumerable <int> > GetAllCoincident <T, U>(IReadOnlyList <T> itemsA, Func <T, Vec2d> getPositionA, IReadOnlyList <U> itemsB, Func <U, Vec2d> getPositionB, HashGrid2d <int> grid, double tolerance = SlurMath.ZeroTolerance)
        {
            grid.Scale = tolerance * RadiusToHashScale;

            // insert B
            for (int i = 0; i < itemsB.Count; i++)
            {
                grid.Insert(getPositionB(itemsB[i]), i);
            }

            // search from A
            for (int i = 0; i < itemsA.Count; i++)
            {
                var p0 = getPositionA(itemsA[i]);

                yield return(grid.Search(new Interval2d(p0, tolerance))
                             .Where(j => p0.ApproxEquals(getPositionB(itemsB[j]), tolerance)));
            }
        }