Ejemplo n.º 1
0
    public void DrawQuadTreeGizmo()
    {
        for (int i = Nodes.Length - 1; i >= 0; i--)
        {
            LinkedQuadTreeNode node = Nodes[i];

            Color color = Color.Lerp(Color.black, Color.white, 1f - ((float)node.Depth / (float)Height));

            DrawNodeGizmo(node, color);
        }
    }
Ejemplo n.º 2
0
    public void InsertValue(int value, LinkedQuadTreeNode node)
    {
        Assert.IsTrue(IsLeaf(node), "Value can be inserted only on leaf node!");

        node.Value = value;

        foreach (LinkedQuadTreeNode n in GetAllParentNodes(node))
        {
            n.Value += value;
        }
    }
Ejemplo n.º 3
0
    public int[] GetCoordinateOfLeafNode(LinkedQuadTreeNode node)
    {
        int sides = NumberOfCellsPerSide(Nodes[0]);

        int indexOffset = GetNumberOfTreeNodes(Height - 1);
        int leafIndex   = node.Index - indexOffset;


        int y = Mathf.FloorToInt(leafIndex / sides);
        int x = leafIndex % sides;

        return(new int[2] {
            x, y
        });
    }
Ejemplo n.º 4
0
    public void DrawNodeGizmo(LinkedQuadTreeNode node, Color color)
    {
        Vector2 position = node.Position;
        float   size     = node.Size;

        Vector2 a = position;
        Vector2 b = position + Vector2.right * size;
        Vector2 c = position + Vector2.up * size;
        Vector2 d = position + Vector2.one * size;

        Debug.DrawLine(a, b, color);
        Debug.DrawLine(b, d, color);
        Debug.DrawLine(d, c, color);
        Debug.DrawLine(c, a, color);
    }
Ejemplo n.º 5
0
    public LinkedQuadTreeNode[] GetAllParentNodes(LinkedQuadTreeNode node, LinkedQuadTreeNode[] parentNodes = null)
    {
        if (parentNodes == null)
        {
            parentNodes = new LinkedQuadTreeNode[node.Depth];
        }

        if (node.Depth > 0)
        {
            LinkedQuadTreeNode parentNode = GetParentNode(node);
            parentNodes[node.Depth - 1] = parentNode;
            return(GetAllParentNodes(parentNode, parentNodes));
        }

        return(parentNodes);
    }
Ejemplo n.º 6
0
    private bool TestGetCoordinateOfLeafNodeHeight3()
    {
        bool   success  = true;
        string messages = "";

        int size   = 128;
        int height = 3;

        LinkedQuadTree     linkedQuadTree = new LinkedQuadTree(Vector2.zero, size, height);
        LinkedQuadTreeNode lastNode       = linkedQuadTree.Nodes[linkedQuadTree.Nodes.Length - 1];

        int[] coordinates = linkedQuadTree.GetCoordinateOfLeafNode(lastNode);
        TestAssert(coordinates[0] == 3, "Expected 3!", ref success, ref messages);
        TestAssert(coordinates[1] == 3, "Expected 3!", ref success, ref messages);

        return(success);
    }
Ejemplo n.º 7
0
    private bool TestGetAllParentNodes()
    {
        bool   success  = true;
        string messages = "";

        int size   = 128;
        int height = 3;

        LinkedQuadTree     linkedQuadTree = new LinkedQuadTree(new Vector2(-size / 2, -size / 2), size, height);
        LinkedQuadTreeNode lastNode       = linkedQuadTree.Nodes[linkedQuadTree.Nodes.Length - 1];

        LinkedQuadTreeNode[] parentNodes = linkedQuadTree.GetAllParentNodes(lastNode);

        TestAssert(parentNodes.Length == 2, "Expected 2 parent nodes!", ref success, ref messages);
        TestAssert(parentNodes[0].Index == 0, "Expected top parent to be root!", ref success, ref messages);
        TestAssert(parentNodes[1].Index == 4, "Expected second parent have index 4!", ref success, ref messages);

        return(success);
    }
Ejemplo n.º 8
0
    private bool TestNumberOfCells()
    {
        bool   success  = true;
        string messages = "";

        int size   = 128;
        int height = 3;

        LinkedQuadTree     linkedQuadTree = new LinkedQuadTree(new Vector2(-size / 2, -size / 2), size, height);
        LinkedQuadTreeNode lastNode       = linkedQuadTree.Nodes[linkedQuadTree.Nodes.Length - 1];

        TestAssert(linkedQuadTree.NumberOfCells(linkedQuadTree.Nodes[0]) == 16, "Expected 4 cells at this depth!", ref success, ref messages);
        TestAssert(linkedQuadTree.NumberOfCells(linkedQuadTree.Nodes[1]) == 4, "Expected 2 cells at this depth!", ref success, ref messages);
        TestAssert(linkedQuadTree.NumberOfCells(lastNode) == 1, "Expected 1 cell at this depth!", ref success, ref messages);

        TestAssert(linkedQuadTree.NumberOfCellsPerSide(linkedQuadTree.Nodes[0]) == 4, "Expected 4 cells at this depth!", ref success, ref messages);
        TestAssert(linkedQuadTree.NumberOfCellsPerSide(linkedQuadTree.Nodes[1]) == 2, "Expected 2 cells at this depth!", ref success, ref messages);
        TestAssert(linkedQuadTree.NumberOfCellsPerSide(lastNode) == 1, "Expected 1 cell at this depth!", ref success, ref messages);

        return(success);
    }
Ejemplo n.º 9
0
    private void BuildQuadTreeRecursively(Vector2 position, float size, int height, int depth = 0, int index = 0, LinkedQuadTreeNode[] nodes = null)
    {
        nodes[index] = new LinkedQuadTreeNode(position, size, depth, index);

        if (depth + 1 >= height)
        {
            return;
        }

        float   sizeHalf  = size * 0.5f;
        Vector2 position1 = position;
        Vector2 position2 = position + Vector2.right * sizeHalf;
        Vector2 position3 = position + Vector2.up * sizeHalf;
        Vector2 position4 = position + Vector2.one * sizeHalf;

        int nextIndex = 4 * index;

        BuildQuadTreeRecursively(position1, sizeHalf, height, depth + 1, nextIndex + 1, nodes);
        BuildQuadTreeRecursively(position2, sizeHalf, height, depth + 1, nextIndex + 2, nodes);
        BuildQuadTreeRecursively(position3, sizeHalf, height, depth + 1, nextIndex + 3, nodes);
        BuildQuadTreeRecursively(position4, sizeHalf, height, depth + 1, nextIndex + 4, nodes);
    }
Ejemplo n.º 10
0
    private bool TestEmptyAndFull()
    {
        int size   = 128;
        int height = 2;

        LinkedQuadTree linkedQuadTree = new LinkedQuadTree(new Vector2(-size / 2, -size / 2), size, height);

        LinkedQuadTreeNode lastNode = linkedQuadTree.Nodes[linkedQuadTree.Nodes.Length - 1];

        linkedQuadTree.InsertValue(1, lastNode);

        bool   success  = true;
        string messages = "";

        TestAssert(linkedQuadTree.IsFull(linkedQuadTree.Nodes[4]) == true, "Expected cell 4 to be full!", ref success, ref messages);
        TestAssert(linkedQuadTree.IsFull(linkedQuadTree.Nodes[0]) == false, "Expected cell 0 not to be full!", ref success, ref messages);
        TestAssert(linkedQuadTree.IsEmpty(linkedQuadTree.Nodes[4]) == false, "Expected cell 4 not to be empty!", ref success, ref messages);
        TestAssert(linkedQuadTree.IsEmpty(linkedQuadTree.Nodes[0]) == false, "Expected cell 0 to be empty!", ref success, ref messages);
        TestAssert(linkedQuadTree.IsEmpty(linkedQuadTree.Nodes[1]) == true, "Expected cell 1 to be emtpy!", ref success, ref messages);

        return(success);
    }
        public LinkedQuadTreeNode <T> Subdivide(Vector2 targetPosition, T newData, int depth = 0)
        {
            if (depth == 0)
            {
                return(this);
            }

            var subdivideIndex = GetIndexOfPosition(targetPosition, position);

            if (subNodes == null)
            {
                subNodes = new LinkedQuadTreeNode <T> [4];

                for (int i = 0; i < subNodes.Length; i++)
                {
                    Vector2 newPos = position;
                    if ((i & 2) == 2)
                    {
                        newPos.y -= size * 0.25f;
                    }
                    else
                    {
                        newPos.y += size * 0.25f;
                    }

                    if ((i & 1) == 1)
                    {
                        newPos.x += size * 0.25f;
                    }
                    else
                    {
                        newPos.x -= size * 0.25f;
                    }

                    subNodes[i] = new LinkedQuadTreeNode <T>(newPos, size * 0.5f, depth - 1);
                }
            }
            return(subNodes[subdivideIndex].Subdivide(targetPosition, newData, depth - 1));
        }
Ejemplo n.º 12
0
 public float NormalizedValue(LinkedQuadTreeNode node)
 {
     return((float)node.Value / NumberOfCells(node));
 }
Ejemplo n.º 13
0
 public int NumberOfCellsPerSide(LinkedQuadTreeNode node)
 {
     return((int)Mathf.Pow(2, Height - 1 - node.Depth));
 }
Ejemplo n.º 14
0
 public bool IsEmpty(LinkedQuadTreeNode node)
 {
     return(node.Value == 0);
 }
Ejemplo n.º 15
0
 public bool IsFull(LinkedQuadTreeNode node)
 {
     return(node.Value == NumberOfCells(node));
 }
Ejemplo n.º 16
0
 public bool IsLeaf(LinkedQuadTreeNode node)
 {
     return(node.Depth + 1 == Height);
 }
Ejemplo n.º 17
0
    public LinkedQuadTreeNode GetParentNode(LinkedQuadTreeNode node)
    {
        int parentIndex = Mathf.FloorToInt((node.Index - 1) / 4);

        return(Nodes[parentIndex]);
    }
        public void CircleSubdivide(LinkedList <LinkedQuadTreeNode <T> > selectectedNodes, Vector2 targetPosition, float radius, T newData, int depth = 0)
        {
            if (depth == 0)
            {
                Data = newData;
                selectectedNodes.AddLast(this);
                return;
            }

            var subdivideIndex = GetIndexOfPosition(targetPosition, position);

            if (IsLeaf())
            {
                subNodes = new LinkedQuadTreeNode <T> [4];

                for (int i = 0; i < subNodes.Length; i++)
                {
                    Vector2 newPosition = position;
                    if ((i & 2) == 2)
                    {
                        newPosition.y -= size * 0.25f;
                    }
                    else
                    {
                        newPosition.y += size * 0.25f;
                    }

                    if ((i & 1) == 1)
                    {
                        newPosition.x += size * 0.25f;
                    }
                    else
                    {
                        newPosition.x -= size * 0.25f;
                    }

                    subNodes[i] = new LinkedQuadTreeNode <T>(newPosition, size * 0.5f, depth - 1, Data);
                }
            }
            for (int i = 0; i < subNodes.Length; i++)
            {
                if (subNodes[i].ContainedInCircle(targetPosition, radius))
                {
                    subNodes[i].CircleSubdivide(selectectedNodes, targetPosition, radius, newData, depth - 1);
                }
            }

            bool shouldReduce = true;
            T    initialData  = subNodes[0].Data;

            for (int i = 0; i < subNodes.Length; i++)
            {
                shouldReduce &= initialData.CompareTo(subNodes[i].Data) == 0;
                shouldReduce &= subNodes[i].IsLeaf();
                if (!shouldReduce)
                {
                    break;
                }
            }
            if (shouldReduce)
            {
                Data     = initialData;
                subNodes = null;
            }
        }
 public LinkedQuadTree(Vector2 position, float size, int depth)
 {
     this.depth = depth;
     node       = new LinkedQuadTreeNode <T>(position, size, depth);
     //node.Subdivide(depth);
 }