コード例 #1
0
        int GetKdNode(KdNodeBounds bounds, int start, int end)
        {
            m_nodes.Add(new KdNode {
                Bounds              = bounds,
                Start               = start,
                End                 = end,
                PartitionAxis       = -1,
                PartitionCoordinate = 0.0f,
                PositiveChildIndex  = -1,
                NegativeChildIndex  = -1
            });

            return(m_nodes.Length - 1);
        }
コード例 #2
0
        /// <summary>
        /// For calculating root node bounds
        /// </summary>
        /// <returns>Boundary of all Vector3 points</returns>
        KdNodeBounds MakeBounds()
        {
            var max  = new float3(float.MinValue, float.MinValue, float.MinValue);
            var min  = new float3(float.MaxValue, float.MaxValue, float.MaxValue);
            int even = Points.Length & ~1;             // calculate even Length

            // min, max calculations
            // 3n/2 calculations instead of 2n
            for (int i0 = 0; i0 < even; i0 += 2)
            {
                int i1 = i0 + 1;

                // X Coords
                if (Points[i0].x > Points[i1].x)
                {
                    // i0 is bigger, i1 is smaller
                    if (Points[i1].x < min.x)
                    {
                        min.x = Points[i1].x;
                    }

                    if (Points[i0].x > max.x)
                    {
                        max.x = Points[i0].x;
                    }
                }
                else
                {
                    // i1 is smaller, i0 is bigger
                    if (Points[i0].x < min.x)
                    {
                        min.x = Points[i0].x;
                    }

                    if (Points[i1].x > max.x)
                    {
                        max.x = Points[i1].x;
                    }
                }

                // Y Coords
                if (Points[i0].y > Points[i1].y)
                {
                    // i0 is bigger, i1 is smaller
                    if (Points[i1].y < min.y)
                    {
                        min.y = Points[i1].y;
                    }

                    if (Points[i0].y > max.y)
                    {
                        max.y = Points[i0].y;
                    }
                }
                else
                {
                    // i1 is smaller, i0 is bigger
                    if (Points[i0].y < min.y)
                    {
                        min.y = Points[i0].y;
                    }

                    if (Points[i1].y > max.y)
                    {
                        max.y = Points[i1].y;
                    }
                }

                // Z Coords
                if (Points[i0].z > Points[i1].z)
                {
                    // i0 is bigger, i1 is smaller
                    if (Points[i1].z < min.z)
                    {
                        min.z = Points[i1].z;
                    }

                    if (Points[i0].z > max.z)
                    {
                        max.z = Points[i0].z;
                    }
                }
                else
                {
                    // i1 is smaller, i0 is bigger
                    if (Points[i0].z < min.z)
                    {
                        min.z = Points[i0].z;
                    }

                    if (Points[i1].z > max.z)
                    {
                        max.z = Points[i1].z;
                    }
                }
            }

            // if array was odd, calculate also min/max for the last element
            if (even != Points.Length)
            {
                // X
                if (min.x > Points[even].x)
                {
                    min.x = Points[even].x;
                }

                if (max.x < Points[even].x)
                {
                    max.x = Points[even].x;
                }

                // Y
                if (min.y > Points[even].y)
                {
                    min.y = Points[even].y;
                }

                if (max.y < Points[even].y)
                {
                    max.y = Points[even].y;
                }

                // Z
                if (min.z > Points[even].z)
                {
                    min.z = Points[even].z;
                }

                if (max.z < Points[even].z)
                {
                    max.z = Points[even].z;
                }
            }

            var b = new KdNodeBounds();

            b.Min = min;
            b.Max = max;
            return(b);
        }
コード例 #3
0
ファイル: KnnContainer.cs プロジェクト: PushoN/KNN
        // TODO: When multiple points overlap exactly this function breaks.
        /// <summary>
        /// Recursive splitting procedure
        /// </summary>
        void SplitNode(int parentIndex, out int posNodeIndex, out int negNodeIndex)
        {
            KdNode parent = m_nodes[parentIndex];

            // center of bounding box
            KdNodeBounds parentBounds     = parent.Bounds;
            float3       parentBoundsSize = parentBounds.Size;

            // Find axis where bounds are largest
            int   splitAxis = 0;
            float axisSize  = parentBoundsSize.x;

            if (axisSize < parentBoundsSize.y)
            {
                splitAxis = 1;
                axisSize  = parentBoundsSize.y;
            }

            if (axisSize < parentBoundsSize.z)
            {
                splitAxis = 2;
            }

            // Our axis min-max bounds
            float boundsStart = parentBounds.Min[splitAxis];
            float boundsEnd   = parentBounds.Max[splitAxis];

            // Calculate the spiting coords
            float splitPivot = CalculatePivot(parent.Start, parent.End, boundsStart, boundsEnd, splitAxis);

            // 'Spiting' array to two sub arrays
            int splittingIndex = Partition(parent.Start, parent.End, splitPivot, splitAxis);

            // Negative / Left node
            float3 negMax = parentBounds.Max;

            negMax[splitAxis] = splitPivot;

            var bounds = parentBounds;

            bounds.Max   = negMax;
            negNodeIndex = GetKdNode(bounds, parent.Start, splittingIndex);

            parent.PartitionAxis       = splitAxis;
            parent.PartitionCoordinate = splitPivot;

            // Positive / Right node
            float3 posMin = parentBounds.Min;

            posMin[splitAxis] = splitPivot;

            bounds       = parentBounds;
            bounds.Min   = posMin;
            posNodeIndex = GetKdNode(bounds, splittingIndex, parent.End);

            parent.NegativeChildIndex = negNodeIndex;
            parent.PositiveChildIndex = posNodeIndex;

            // Write back node to array to update those values
            m_nodes[parentIndex] = parent;
        }