示例#1
0
        public PointCloud FindClosestPointCloud_Parallel(PointCloud source)
        {
            this.source = source;
            this.ResetTaken();


            VertexKDTree[] resultArray = new VertexKDTree[source.Count];

            System.Threading.Tasks.Parallel.For(0, source.Count, i =>
                                                //for (int i = 0; i < source.Count; i++)
            {
                VertexKDTree vSource = new VertexKDTree(source.Vectors[i], i);

                int nearest_index         = 0;
                float nearest_distance    = 0f;
                VertexKDTree vTargetFound = FindClosestPoint(vSource, ref nearest_distance, ref nearest_index);

                //resultArray[i] = vTargetFound.Clone();
                resultArray[i] = vTargetFound;
            });

            List <VertexKDTree> resultList = new List <VertexKDTree>(resultArray);

            result = PointCloud.FromListVertexKDTree(resultList);


            return(result);
        }
示例#2
0
        /// <summary>
        /// Return the KDTreeNode that 'vertex' belongs to according to the split axis.
        /// </summary>
        /// <param name="vertex">3D vertex to bin</param>
        /// <returns>KDTreeNode containing 'vertex'</returns>
        public KDNodeJeremyC GetSplitNode(VertexKDTree vertex)
        {
            if (ChildLeft == null || ChildRight == null)
            {
                ChildLeft = new KDNodeJeremyC {
                    Parent = this
                };
                ChildRight = new KDNodeJeremyC {
                    Parent = this
                };

                ChildLeft.Sibling  = ChildRight;
                ChildRight.Sibling = ChildLeft;
            }


            float mid_value = Leaf.Vector[(int)SplitAxis];
            float pt_value  = vertex.Vector[(int)SplitAxis];

            //float diff = pt_value - mid_value;
            //float diff2 = Math.Abs(diff / pt_value);

            //if (diff > 0)
            //    return ChildLeft;
            //else if (diff < 0 && diff2 < 1e-7)
            //    return ChildLeft;
            //else
            //    return ChildRight;
            KDNodeJeremyC child = (pt_value >= mid_value) ? ChildLeft : ChildRight;

            return(child);
        }
示例#3
0
        public bool SearchNode(VertexKDTree v, KDNode node, float bestDistance)
        {
            //  float bestDistance = float.MaxValue;

            float dist = node.Leaf.Vector.Distance(v.Vector);

            if (dist < bestDistance && !node.Taken)
            {
                bestDistance = dist;
                node.Taken   = true;
                v.Index      = node.Leaf.Index;
            }

            if (node.NodeLeft != null)
            {
                //float dist = node.Leaf.Vector.Distance(v.Vector);
                if (dist < bestDistance && !node.Taken)
                {
                    bestDistance = dist;
                    node.Taken   = true;
                    v.Index      = node.Leaf.Index;
                }
            }
            return(true);
        }
        /// <summary>
        /// Based upon the info of the nearest vertex (of each vertex), the triangles are created
        /// </summary>
        /// <param name="myModel"></param>
        //private static List<Triangle> CreateTrianglesByNearestVertices(PointCloud pointCloud)
        //{

        //    List<Triangle> listTriangles = new List<Triangle>();

        //    //create triangles
        //    //for (int i = pointCloud.Count - 1; i >= 0; i--)
        //    for (int i = 0; i < pointCloud.Count; i++)
        //    {
        //        Vertex v = pointCloud[i];

        //        if (v.KDTreeSearch.Count >= 2)
        //        {
        //            Triangle.AddTriangleToList(v.Index, v.KDTreeSearch[0].Key, v.KDTreeSearch[1].Key, listTriangles, v);


        //        }
        //        if (v.KDTreeSearch.Count >= 3)
        //        {
        //            Triangle.AddTriangleToList(v.Index, v.KDTreeSearch[0].Key, v.KDTreeSearch[2].Key, listTriangles, v);
        //            Triangle.AddTriangleToList(v.Index, v.KDTreeSearch[1].Key, v.KDTreeSearch[2].Key, listTriangles, v);


        //        }
        //        if (v.KDTreeSearch.Count >= 4)
        //        {
        //            Triangle.AddTriangleToList(v.Index, v.KDTreeSearch[0].Key, v.KDTreeSearch[3].Key, listTriangles, v);
        //            Triangle.AddTriangleToList(v.Index, v.KDTreeSearch[1].Key, v.KDTreeSearch[3].Key, listTriangles, v);
        //            Triangle.AddTriangleToList(v.Index, v.KDTreeSearch[2].Key, v.KDTreeSearch[3].Key, listTriangles, v);

        //        }
        //        if (v.KDTreeSearch.Count >= 5)
        //        {
        //            Triangle.AddTriangleToList(v.Index, v.KDTreeSearch[0].Key, v.KDTreeSearch[4].Key, listTriangles, v);
        //            Triangle.AddTriangleToList(v.Index, v.KDTreeSearch[1].Key, v.KDTreeSearch[4].Key, listTriangles, v);
        //            Triangle.AddTriangleToList(v.Index, v.KDTreeSearch[2].Key, v.KDTreeSearch[4].Key, listTriangles, v);
        //            Triangle.AddTriangleToList(v.Index, v.KDTreeSearch[3].Key, v.KDTreeSearch[4].Key, listTriangles, v);

        //        }



        //    }
        //    //RemoveDuplicateTriangles(listTriangles);
        //    listTriangles.Sort(new TriangleComparer());

        //    return listTriangles;
        //}

        public void Triangulate_KDTree(int numberNeighbours)
        {
            KDTreeKennell kdTree = new KDTreeKennell();

            kdTree.Build(this);

            List <Triangle> listTriangles = new List <Triangle>();

            for (int i = 0; i < this.Vectors.Length; i++)
            {
                VertexKDTree vSource = new VertexKDTree(this.Vectors[i], this.Colors[i], i);
                uint         indexI  = Convert.ToUInt32(i);

                ListKDTreeResultVectors listResult = kdTree.Find_N_Nearest(vSource.Vector, numberNeighbours);
                for (int j = 1; j < listResult.Count; j++)
                {
                    for (int k = j + 1; k < listResult.Count; k++)
                    {
                        Triangle t = new Triangle(indexI, listResult[j].IndexNeighbour, listResult[k].IndexNeighbour);
                        listTriangles.Add(t);
                    }
                }
            }
            this.Triangles = listTriangles;


            CreateIndicesFromTriangles();
        }
示例#5
0
        /// <summary>
        /// Recursively split node across its pivot axis.
        /// </summary>
        /// <param name="node">KDTreeNode to split</param>
        /// <param name="depth">Current recursion depth, set lower if you get stack overflow</param>
        /// <returns>True if split was a success or max_depth/max_node_size criterion met</returns>
        bool BuildNode(KDNodeJeremyC node, int depth)
        {
            if (depth >= MaxNodeDepth)
            {
                return(true);
            }
            if (node.Indices.Count <= MaxNodeSize)
            {
                return(true);
            }

            foreach (var index in node.Indices)
            {
                VertexKDTree vertex = TreeVectors[index];

                if (!node.IsBuilt)
                {
                    node.Build();
                }
                KDNodeJeremyC child = node.GetSplitNode(vertex);
                child.AddVertex(index, vertex);
            }

            // TODO:  Do we need to check if either child is empty?  Since we're calculating the split axis
            //		  using raw data it's unlikely.
            node.Clear();
            node.ChildLeft.Build();
            node.ChildRight.Build();

            BuildNode(node.ChildLeft, depth + 1);
            BuildNode(node.ChildRight, depth + 1);
            return(true);
        }
示例#6
0
 public KDNode(VertexKDTree v, List <VertexKDTree> myListLeft, List <VertexKDTree> myListRight)
 {
     Leaf      = v;
     NodeLeft  = KDTree.BuildNode(myListLeft);
     NodeRight = KDTree.BuildNode(myListRight);
     //ListLeft = myListLeft;
     //ListRight= myListRight;
 }
示例#7
0
        /// <summary>
        /// returns the target (tree) points found for the input (source) points
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public PointCloud FindClosestPointCloud_Parallel(PointCloud source)
        {
            this.source = source;
            this.ResetTaken();


            VertexKDTree[] resultArray = new VertexKDTree[source.Count];

            //shuffle points for the "Taken" algorithm
            PointCloud sourceShuffled;

            if (this.TakenAlgorithm)
            {
                sourceShuffled = source.Clone();
                sourceShuffled.SetDefaultIndices();
                sourceShuffled = PointCloud.Shuffle(sourceShuffled);
            }
            else
            {
                sourceShuffled = source;
            }

            int   nearest_index    = 0;
            float nearest_distance = 0f;

            System.Threading.Tasks.Parallel.For(0, source.Count, i =>
                                                //for (int i = 0; i < sourceShuffled.Count; i++)
            {
                VertexKDTree vSource      = new VertexKDTree(sourceShuffled.Vectors[i], i);
                VertexKDTree vTargetFound = FindClosestPoint(vSource, ref nearest_distance, ref nearest_index);
                //resultArray[i] = vTargetFound.Clone();
                resultArray[i] = vTargetFound;
            });

            List <VertexKDTree> resultList = new List <VertexKDTree>(resultArray);

            result = PointCloud.FromListVertexKDTree(resultList);

            //shuffle back

            PointCloud pcResultShuffledBack;

            if (this.TakenAlgorithm)
            {
                pcResultShuffledBack = result.Clone();
                for (int i = 0; i < pcResultShuffledBack.Count; i++)
                {
                    //pcResultShuffled.Vectors[i] = pcResult.Vectors[Convert.ToInt32(sourceShuffled.Indices[i])];
                    pcResultShuffledBack.Vectors[Convert.ToInt32(sourceShuffled.Indices[i])] = result.Vectors[i];
                }
            }
            else
            {
                pcResultShuffledBack = result;
            }
            //this.MeanDistance = PointCloud.MeanDistance(source, pcResultShuffledBack);
            return(pcResultShuffledBack);
        }
示例#8
0
        /// <summary>
        /// Find closest point using an axis aligned search boundary
        /// </summary>
        /// <param name="node"></param>
        /// <param name="point"></param>
        /// <returns></returns>
        VertexKDTree FindClosestPoint_Recursive(KDNodeJeremyC node, VertexKDTree vertex, BoundingBoxAxisAligned search_bounds, ref int nearest_index)
        {
            int tmp_index = -1;

            if (node.IsLeaf)
            {
                tmp_index = -1;
                VertexKDTree result = GetClosestVertexFromIndices(node.Indices, vertex, ref tmp_index);
                if (result != null)
                {
                    nearest_index = tmp_index;
                    return(result);
                }
                else
                {
                    return(null);
                }
            }

            tmp_index = -1;
            KDNodeJeremyC near_child = node.GetSplitNode(vertex);

            VertexKDTree retV = FindClosestPoint_Recursive(near_child, vertex, search_bounds, ref tmp_index);
            //Edgar - TakenVector implementation - have to go one level up if vector is taken
            float near_distance = float.MaxValue;

            if (retV != null)
            {
                //near_distance = retV.Vector.Distance(vertex.Vector);
                near_distance = retV.Vector.DistanceSquared(vertex.Vector);
                nearest_index = tmp_index;
            }

            KDNodeJeremyC far_child = near_child.Sibling;

            if (search_bounds != null && far_child.BoundingBox.Intersects(search_bounds))
            {
                VertexKDTree far_result = FindClosestPoint_Recursive(far_child, vertex, search_bounds, ref tmp_index);
                //Edgar - TakenVector implementation - have to go one level up if vector is taken
                if (far_result != null)
                {
                    //float far_distance = far_result.Vector.Distance(vertex.Vector);
                    float far_distance = far_result.Vector.DistanceSquared(vertex.Vector);
                    if (far_distance < near_distance)
                    {
                        nearest_index = tmp_index;
                        retV          = far_result;
                    }
                }
            }

            if (retV == null)
            {
            }
            return(retV);
        }
示例#9
0
        public void Search(PointCloud pcl)
        {
            List <VertexKDTree> list = new List <VertexKDTree>(pcl.VectorsWithIndex);

            for (int i = 0; i < list.Count; i++)
            {
                VertexKDTree v = list[i];
                //if(v.Vector.Distance())
                //for(int j = 0; j < this.RootNode.)
            }
        }
示例#10
0
        /// <summary>
        /// Utility method to build KDTreeNode variables, as long as min and max
        /// </summary>
        public void Build()
        {
            Leaf   = new VertexKDTree(new Vector3(maxV + minV) / 2.0f, -1);
            rangeV = maxV - minV;

            SplitAxis = rangeV.LargestAxis();

            BoundingBox = new BoundingBoxAxisAligned(minV, maxV);

            IsBuilt = true;
        }
示例#11
0
 /// <summary>
 /// Add a new vertex, and its index, to node.
 /// </summary>
 /// <param name="index">Index in to KDTree's vertices List</param>
 /// <param name="vertex">Actual vertex from KDTree's vertex list</param>
 public void AddVertex(int index, VertexKDTree vertex)
 {
     if (Indices.Count == 0)
     {
         minV = maxV = vertex.Vector;
     }
     minV = Vector3.Min(minV, vertex.Vector);
     maxV = Vector3.Max(maxV, vertex.Vector);
     Indices.Add(index);
     IsBuilt = false;
 }
示例#12
0
        /// <summary>
        /// FInd the closest matching point using a full For-loop search: O(n)
        /// </summary>
        /// <param name="vertex">Vertex to match</param>
        /// <param name="nearest_index">Index of matching vertex in the KDTree vertex array</param>
        /// <returns>Nearest matching vertex</returns>
        public VertexKDTree FindClosestPoint(VertexKDTree vertex, ref float nearestDistance, ref int nearest_index)
        {
            float[] array = new float[] { vertex.Vector.X, vertex.Vector.Y, vertex.Vector.Z };
            Tuple <float[], string>[] treeNearest = tree.NearestNeighbors(array, 1);

            Tuple <float[], string> p = treeNearest[0];


            VertexKDTree v = new VertexKDTree();

            v.Vector = new Vector3(p.Item1[0], p.Item1[1], p.Item1[2]);

            return(v);
        }
示例#13
0
        /// <summary>
        /// FInd the closest matching point using a full For-loop search: O(n)
        /// </summary>
        /// <param name="vertex">Vertex to match</param>
        /// <param name="nearest_index">Index of matching vertex in the KDTree vertex array</param>
        /// <returns>Nearest matching vertex</returns>
        public VertexKDTree FindClosestPoint(VertexKDTree vertex, ref float nearestDistance, ref int nearest_index)
        {
            VertexKDTree v = new VertexKDTree();

            ListKDTreeResultVectors listResult = Find_N_Nearest(vertex.Vector, 1);

            if (listResult != null && listResult.Count > 0)
            {
                nearest_index   = Convert.ToInt32(listResult[0].IndexNeighbour);
                nearestDistance = listResult[0].Distance;
                v = this.TreeVectors[Convert.ToInt32(listResult[0].IndexNeighbour)];
            }

            return(v);
        }
示例#14
0
        /// <summary>
        /// Algorithm based on ignoring points with less neighbours    int thresholdNeighboursCount = 10; float thresholdDistance = 15e-5f;
        /// at given distance.
        /// </summary>
        /// <param name="source"></param>
        /// <param name="threshold"></param>
        /// <returns></returns>
        public static PointCloud ByLessNeighbours(PointCloud source, float thresholdDistance, int thresholdNeighboursCount)
        {
            PointCloud pcResult = new PointCloud();

            KDTreeKennell kdTree = new KDTreeKennell();

            kdTree.Build(source);


            VertexKDTree[] resultArray = new VertexKDTree[source.Count];

            try
            {
                List <Vector3> listV = new List <Vector3>();
                List <Vector3> listC = new List <Vector3>();
                System.Threading.Tasks.Parallel.For(0, source.Count, i =>
                {
                    VertexKDTree vSource = new VertexKDTree(source.Vectors[i], source.Colors[i], i);
                    int neighboursCount  = 0;

                    kdTree.FindClosestPoints_Radius(vSource, thresholdDistance, ref neighboursCount);

                    if (neighboursCount >= thresholdNeighboursCount)
                    {
                        resultArray[i] = vSource;
                    }
                });

                for (int i = 0; i < source.Count; i++)
                {
                    if (resultArray[i] != null)
                    {
                        listV.Add(resultArray[i].Vector);
                        listC.Add(resultArray[i].Color);
                    }
                }

                pcResult.Vectors = listV.ToArray();
                pcResult.Colors  = listC.ToArray();
                pcResult.SetDefaultIndices();
            }
            catch (Exception err)
            {
                System.Windows.Forms.MessageBox.Show("Error in KDTreeKennnellRemoveDuplicates: " + err.Message);
            }

            return(pcResult);
        }
示例#15
0
        private List <VertexKDTree> FindClosestPoint_List_Parallel(List <VertexKDTree> source)
        {
            this.ResetTaken();


            VertexKDTree[] vArray = source.ToArray();
            System.Threading.Tasks.Parallel.For(0, source.Count, i =>
            {
                int nearest_index         = 0;
                float nearest_distance    = 0f;
                VertexKDTree vTargetFound = FindClosestPoint(vArray[i], ref nearest_distance, ref nearest_index);
                vArray[i] = vTargetFound.Clone();
            });

            return(new List <VertexKDTree>(vArray));
        }
示例#16
0
        public void FindClosestPoints_Radius(VertexKDTree vertex, float radius, ref int neighboursCount)
        {
            // search for all within a ball of a certain radius
            //ListKDTreeResultVectors result = new ListKDTreeResultVectors();

            SearchRecord sr = new SearchRecord(vertex.Vector);

            // Vector3 vdiff = new Vector3();

            sr.Radius = radius;

            root.search(sr);

            ListKDTreeResultVectors listResult = sr.SearchResult;

            neighboursCount = listResult.Count;
        }
示例#17
0
        /// <summary>
        /// Find the closest matching vertex
        /// </summary>
        /// <param name="vertex">Vertex to find closest match.</param>
        /// <param name="distance">Search distance.</param>
        /// <param name="nearest_index">Index of matching vertex in the KDTree vertex array</param>
        /// <returns>Nearest matching vertex</returns>
        public VertexKDTree FindClosestPoint(VertexKDTree vertex, ref float distance, ref int nearest_index)
        {
            if (root == null)
            {
                Console.WriteLine("Null root, Build() must be called before using the KDTree.");
                return(new VertexKDTree(new Vector3(0, 0, 0), -1));
            }

            BoundingBoxAxisAligned search_bounds = null;

            if (distance != 0)
            {
                Vector3 distance_vector = new Vector3(distance, distance, distance);
                search_bounds = new BoundingBoxAxisAligned(vertex.Vector - distance_vector, vertex.Vector + distance_vector);
            }
            return(FindClosestPoint_Recursive(Root, vertex, search_bounds, ref nearest_index));
        }
示例#18
0
        public static KDNode BuildNode(List <VertexKDTree> list)
        {
            if (list.Count <= 1)
            {
                if (list.Count == 0)
                {
                    return(null);
                }
                else
                {
                    return(new KDNode(list[0]));
                }
            }


            //check length even or odd
            int medianIndex = list.Count / 2;

            if (list.Count % 2 == 0)
            {
                medianIndex = list.Count / 2;
            }
            else
            {
                medianIndex = list.Count / 2;
            }



            VertexKDTree leaf = list[medianIndex];

            List <VertexKDTree> listLeft = new List <VertexKDTree>();

            listLeft.AddRange(list);
            listLeft.RemoveRange(medianIndex, list.Count - medianIndex);
//            if(listLeft.Count > 0)


            List <VertexKDTree> listRight = new List <VertexKDTree>();

            listRight.AddRange(list);
            listRight.RemoveRange(0, medianIndex + 1);

            return(new KDNode(leaf, listLeft, listRight));
        }
示例#19
0
        public PointCloud RemoveDuplicates(PointCloud source, float threshold)
        {
            PointCloud pcResult = new PointCloud();

            VertexKDTree[] resultArray = new VertexKDTree[source.Count];

            try
            {
                List <Vector3> listV = new List <Vector3>();
                List <Vector3> listC = new List <Vector3>();

                System.Threading.Tasks.Parallel.For(0, source.Count, i =>
                {
                    VertexKDTree vSource      = new VertexKDTree(source.Vectors[i], i);
                    int nearest_index         = 0;
                    float nearest_distance    = 0f;
                    VertexKDTree vTargetFound = FindClosestPoint(vSource, ref nearest_distance, ref nearest_index);
                    if (nearest_distance > threshold)
                    {
                        resultArray[i] = vSource;
                    }
                });
                //add only the non null list items
                for (int i = 0; i < source.Count; i++)
                {
                    if (resultArray[i] != null)
                    {
                        listV.Add(resultArray[i].Vector);
                        listC.Add(resultArray[i].Color);
                    }
                }
                pcResult.Vectors = listV.ToArray();
                pcResult.Colors  = listC.ToArray();
            }
            catch (Exception err)
            {
                System.Windows.Forms.MessageBox.Show("Error in KDTreeKennnellRemoveDuplicates: " + err.Message);
            }
            return(pcResult);
        }
示例#20
0
        /// <summary>
        /// FInd the closest matching point using a full For-loop search: O(n)
        /// </summary>
        /// <param name="vertex">Vertex to match</param>
        /// <param name="nearest_index">Index of matching vertex in the KDTree vertex array</param>
        /// <returns>Nearest matching vertex</returns>
        public VertexKDTree FindClosestPoint(VertexKDTree vertex, ref float nearestDistance, ref int nearest_index)
        {
            float min_dist  = 0.0f;
            int   min_index = -1;

            for (int j = 0; j < TreeVectors.Count; j++)
            {
                VertexKDTree tmp_vertex = TreeVectors[j];
                //float distance = tmp_vertex.Vector.Distance(vertex.Vector);
                float distance = tmp_vertex.Vector.DistanceSquared(vertex.Vector);
                if (min_index == -1)
                {
                    min_dist  = distance;
                    min_index = j;
                }
                else
                {
                    if (distance < min_dist)
                    {
                        if (!this.TakenAlgorithm)
                        {
                            min_dist  = distance;
                            min_index = j;
                        }
                        else
                        {
                            if (!tmp_vertex.TakenInTree)
                            {
                                tmp_vertex.TakenInTree = true;
                                min_dist  = distance;
                                min_index = j;
                            }
                        }
                    }
                }
            }
            nearest_index = min_index;
            return(TreeVectors[min_index]);
        }
示例#21
0
        //assumes a 2.5 D point cloud (i.e. for a given x,y there is only ONE z value
        public void Triangulate25D(float distMin)
        {
            float meanDistance, standardDeviation;

            float[] distances;
            //1. get standard deviation, meanDistance and array of distances
            Outliers.StandardDeviation(this, 10, out meanDistance, out standardDeviation, out distances);

            distMin = meanDistance * 100;

            this.Triangles = new List <Triangle>();

            List <List <VertexKDTree> > listNew = SortVectorsWithIndex();

            for (int i = listNew.Count - 1; i > 0; i--)
            {
                List <VertexKDTree> columnx = listNew[i];
                List <VertexKDTree> columny = listNew[i - 1];
                for (int j = 1; j < columnx.Count; j++)
                {
                    VertexKDTree vx     = columnx[j];
                    float        dist_x = columnx[j - 1].Vector.Distance(vx.Vector);
                    if (dist_x < distMin)
                    {
                        foreach (VertexKDTree vy in columny)
                        {
                            float dist_xy = vx.Vector.Distance(vy.Vector);
                            if (dist_xy < distMin)
                            {
                                Triangles.Add(new Triangle(columnx[j - 1].Index, vx.Index, vy.Index));
                            }
                        }
                    }
                }
            }
            CreateIndicesFromTriangles();
        }
示例#22
0
        /// <summary>
        /// Iterate through System.IO.Collections.Generic.List<int> to find closest matching vertex
        /// </summary>
        /// <param name="indices">List of integer indices that index vertices</param>
        /// <param name="vertex">Vertex to match</param>
        /// <returns>Closest stored 'vertex' to given 'vertex'</returns>
        VertexKDTree GetClosestVertexFromIndices(List <int> indices, VertexKDTree vertex, ref int nearest_index)
        {
            int   min_index = -1;
            float min_dist  = 0.0f;

            foreach (var index in indices)
            {
                VertexKDTree tmp_vertex = TreeVectors[index];
                if (!(TakenAlgorithm && tmp_vertex.TakenInTree))
                {
                    if (min_index == -1)
                    {
                        //min_dist = tmp_vertex.Vector.Distance(vertex.Vector);
                        min_dist  = tmp_vertex.Vector.DeltaSquared(vertex.Vector);
                        min_index = index;
                    }
                    else
                    {
                        //float tmp_dist = tmp_vertex.Vector.Distance(vertex.Vector);
                        float tmp_dist = tmp_vertex.Vector.DistanceSquared(vertex.Vector);

                        if (tmp_dist < min_dist)
                        {
                            min_dist  = tmp_dist;
                            min_index = index;
                        }
                    }
                }
            }
            nearest_index = min_index;
            if (min_index != -1)
            {
                TreeVectors[min_index].TakenInTree = true;
                return(TreeVectors[min_index]);
            }
            return(null);
        }
示例#23
0
        /// <summary>
        /// Find closest point using a centered bounding sphere
        /// </summary>
        /// <param name="node"></param>
        /// <param name="vertex"></param>
        /// <param name="search_bounds"></param>
        /// <param name="nearest_index"></param>
        /// <returns></returns>
        VertexKDTree FindClosestPoint(KDNodeJeremyC node, VertexKDTree vertex, BoundingSphere search_bounds, ref int nearest_index)
        {
            int tmp_index = -1;

            if (node.IsLeaf)
            {
                tmp_index = -1;
                VertexKDTree result = GetClosestVertexFromIndices(node.Indices, vertex, ref tmp_index);
                nearest_index = tmp_index;
                return(result);
            }

            tmp_index = -1;
            KDNodeJeremyC near_child  = node.GetSplitNode(vertex);
            VertexKDTree  near_result = FindClosestPoint(near_child, vertex, search_bounds, ref tmp_index);
            VertexKDTree  ret         = near_result;
            //float near_distance = near_result.Vector.Distance(vertex.Vector);
            float near_distance = near_result.Vector.DistanceSquared(vertex.Vector);

            nearest_index = tmp_index;

            KDNodeJeremyC far_child = near_child.Sibling;

            if (far_child.BoundingBox.Intersects(search_bounds))
            {
                VertexKDTree far_result   = FindClosestPoint(far_child, vertex, search_bounds, ref tmp_index);
                float        far_distance = far_result.Vector.DistanceSquared(vertex.Vector);
                //float far_distance = far_result.Vector.Distance(vertex.Vector);
                if (far_distance < near_distance)
                {
                    nearest_index = tmp_index;
                    ret           = far_result;
                }
            }
            return(ret);
        }
示例#24
0
        //public void CreateIndicesFromNewTriangles(List<OpenTKExtension.TriangleVectors> listTriangles)
        //{
        //    if (listTriangles != null)
        //    {
        //        this.Indices = new uint[listTriangles.Count * 3];
        //        int ind = 0;
        //        Triangles = new List<Triangle>();
        //        foreach (OpenTKExtension.TriangleVectors t in listTriangles)
        //        {

        //            this.Indices[ind++] = Convert.ToUInt32(t.A_Index);
        //            this.Indices[ind++] = Convert.ToUInt32(t.B_Index);
        //            this.Indices[ind++] = Convert.ToUInt32(t.C_Index);
        //            Triangles.Add(new Triangle(Convert.ToInt32(t.A_Index), Convert.ToInt32(t.B_Index), Convert.ToInt32(t.C_Index)));
        //        }
        //    }
        //}


        private List <List <VertexKDTree> > SortVectorsWithIndex()
        {
            List <List <VertexKDTree> > listNew = new List <List <VertexKDTree> >();

            List <VertexKDTree> listOld = new List <VertexKDTree>(this.VectorsWithIndex);

            List <VertexKDTree> column = new List <VertexKDTree>();
            bool positiveValues        = false;

            //for (int i = listOld.Count - 1; i >= 0; i--)
            for (int i = 0; i < listOld.Count; i++)
            {
                VertexKDTree v = listOld[i];

                if (v.Vector.Y < 0 && !positiveValues)
                {
                    column.Add(v);
                }
                else if (v.Vector.Y > 0 && !positiveValues)
                {
                    positiveValues = true;
                    column.Add(v);
                }
                else if (v.Vector.Y > 0)
                {
                    column.Add(v);
                }
                else if (v.Vector.Y < 0 && positiveValues)
                {
                    positiveValues = false;
                    listNew.Add(column);
                    column = new List <VertexKDTree>();
                }
            }
            return(listNew);
        }
示例#25
0
        public static void StandardDeviation(PointCloud source, int numberOfNeighbours, out float meanDistance, out float standardDeviation, out float[] distances)
        {
            meanDistance      = 0;
            standardDeviation = 0f;
            distances         = new float[source.Count];

            KDTreeKennell kdTree = new KDTreeKennell();

            kdTree.Build(source);


            PointCloud pcResult = new PointCloud();


            VertexKDTree[] resultArray = new VertexKDTree[source.Count];
            VertexKDTree[] outliers    = new VertexKDTree[source.Count];

            try
            {
                List <Vector3> listV = new List <Vector3>();
                List <Vector3> listC = new List <Vector3>();



                //1. mean distance of one point to his next "numberOfNeighbours" neighbours - stored in the "distances" array
                for (int i = 0; i < source.Count; i++)
                {
                    VertexKDTree vSource = new VertexKDTree(source.Vectors[i], source.Colors[i], i);

                    ListKDTreeResultVectors listResult = kdTree.Find_N_Nearest(vSource.Vector, numberOfNeighbours);

                    float distSum = 0f;
                    for (int k = 1; k < listResult.Count; ++k)  // k = 0 is the query point
                    {
                        distSum += listResult[k].Distance;
                    }

                    distances[i] = (distSum / (listResult.Count - 1));
                }
                //2. calculate the mean distance of ALL points



                for (int i = 0; i < distances.Length; ++i)
                {
                    meanDistance += distances[i];
                }
                meanDistance /= distances.Length;

                //3. calculate the deviation of each data point from the mean, and square the result of each

                for (int i = 0; i < distances.Length; i++)
                {
                    float dev = distances[i] - meanDistance;
                    dev *= dev;
                    standardDeviation += dev;
                }
                standardDeviation /= distances.Length;
                standardDeviation  = Convert.ToSingle(Math.Sqrt(standardDeviation));
            }
            catch (Exception err)
            {
                System.Windows.Forms.MessageBox.Show("Error in KDTreeKennnellRemoveDuplicates: " + err.Message);
            }
        }
示例#26
0
        public VertexKDTree Clone()
        {
            VertexKDTree v = new VertexKDTree(this.Vector, this.Index);

            return(v);
        }
示例#27
0
        /// <summary>
        /// tree.RemoveOutliersByDeviation(PointCloudDirty, 10, 1.3f);
        /// </summary>
        /// <param name="source"></param>
        /// <param name="numberOfNeighbours"></param>
        /// <param name="stdMultiplier"></param>
        /// <returns></returns>
        public static PointCloud ByStandardDeviation(PointCloud source, int numberOfNeighbours, float stdDeviationMultiplier, out PointCloud pcOutliersMarkedRed)
        {
            PointCloud pcResult = new PointCloud();

            //the outliers are marked red
            pcOutliersMarkedRed = source.Clone();

            float meanDistance, standardDeviation;

            float[] distances;
            //1. get standard deviation, meanDistance and array of distances
            StandardDeviation(source, numberOfNeighbours, out meanDistance, out standardDeviation, out distances);


            int numberRemoved = 0;

            VertexKDTree[] resultArray = new VertexKDTree[source.Count];
            VertexKDTree[] outliers    = new VertexKDTree[source.Count];

            try
            {
                List <Vector3> listV = new List <Vector3>();
                List <Vector3> listC = new List <Vector3>();

                //2. distance threshold: deviation plus the overall mean distance
                float distanceThreshold = meanDistance + standardDeviation;


                //3. remove all points according to the distance threshold
                for (int i = 0; i < source.Count; i++)
                {
                    VertexKDTree vSource = new VertexKDTree(source.Vectors[i], source.Colors[i], i);

                    if (distances[i] > distanceThreshold)
                    {
                        pcOutliersMarkedRed.Colors[i] = new Vector3(1, 0, 0);
                        numberRemoved++;
                        continue;
                    }
                    else
                    {
                        resultArray[i] = vSource;
                    }
                }

                List <Vector3> listOutliers       = new List <Vector3>();
                List <Vector3> listOutliersColors = new List <Vector3>();
                //build resulting cloud and outliers
                for (int i = 0; i < source.Count; i++)
                {
                    if (resultArray[i] != null)
                    {
                        listV.Add(resultArray[i].Vector);
                        listC.Add(resultArray[i].Color);
                    }
                }

                pcResult.Vectors = listV.ToArray();
                pcResult.Colors  = listC.ToArray();
                pcResult.SetDefaultIndices();

                System.Diagnostics.Debug.WriteLine("Outliers: Mean distance---" + meanDistance.ToString("G") + " ---- standard deviation ---" + standardDeviation.ToString("G") + "---Number of outliers: " + numberRemoved.ToString());
            }
            catch (Exception err)
            {
                System.Windows.Forms.MessageBox.Show("Error in KDTreeKennnellRemoveDuplicates: " + err.Message);
            }

            return(pcResult);
        }
示例#28
0
 public KDNode(VertexKDTree v)
 {
     Leaf = v;
 }