예제 #1
0
    public LODMeshObject(LODMeshObject parent, QuadTreeNode quadTreeNode, AxisAlignedRectangle bounds, int depth)
    {
        Invalid = true;
        Parent = parent;
        QuadNode = quadTreeNode;
        Bounds = bounds;
        Depth = depth;
        TotalDepth = QuadNode.Depth + Depth;
        Children = new LODMeshObject[4];
        CornerReference = new bool[5];

        Center = FindOrCreateCorner(Bounds.Position, true);

        Vector2 halfSize = Bounds.Size / 2;
        Corner = new Corner[8];
        Corner[0] = FindOrCreateCorner(Bounds.Position + new Vector2(-halfSize.x, -halfSize.y), Parent == null); // bottom left
        Corner[1] = FindOrCreateCorner(Bounds.Position + new Vector2(-halfSize.x, 0), true); // left

        Corner[2] = FindOrCreateCorner(Bounds.Position + new Vector2(-halfSize.x, halfSize.y), Parent == null); // top left
        Corner[3] = FindOrCreateCorner(Bounds.Position + new Vector2(0, halfSize.y), true); // top

        Corner[4] = FindOrCreateCorner(Bounds.Position + new Vector2(halfSize.x, halfSize.y), Parent == null); // top right
        Corner[5] = FindOrCreateCorner(Bounds.Position + new Vector2(halfSize.x, 0), true); // right

        Corner[6] = FindOrCreateCorner(Bounds.Position + new Vector2(halfSize.x, -halfSize.y), Parent == null); // bottom right
        Corner[7] = FindOrCreateCorner(Bounds.Position + new Vector2(0, -halfSize.y), true); // bottom
    }
예제 #2
0
    public void Grow(Vector2 direction)
    {
        QuadTreeNode tempRoot = null;
        if (direction == new Vector2(1, 1))
        {
            tempRoot = new QuadTreeNode(this, null, Root.AAR.Position + new Vector2(Root.AAR.Size.x / 2, Root.AAR.Size.y / 2), (Root.AAR.Size.x + Root.AAR.Size.y) / 2, Root.MinSize, 0);
            tempRoot.MeshObject.Children[0] = Root.MeshObject;
        }
        if (direction == new Vector2(-1, -1))
        {
            tempRoot = new QuadTreeNode(this, null, Root.AAR.Position + new Vector2(-Root.AAR.Size.x / 2, -Root.AAR.Size.y / 2), (Root.AAR.Size.x + Root.AAR.Size.y) / 2, Root.MinSize, 0);
            tempRoot.MeshObject.Children[2] = Root.MeshObject;
        }
        if (direction == new Vector2(1, -1))
        {
            tempRoot = new QuadTreeNode(this, null, Root.AAR.Position + new Vector2(Root.AAR.Size.x / 2, -Root.AAR.Size.y / 2), (Root.AAR.Size.x + Root.AAR.Size.y) / 2, Root.MinSize, 0);
            tempRoot.MeshObject.Children[1] = Root.MeshObject;
        }
        if (direction == new Vector2(-1, 1))
        {
            tempRoot = new QuadTreeNode(this, null, Root.AAR.Position + new Vector2(-Root.AAR.Size.x / 2, Root.AAR.Size.y / 2), (Root.AAR.Size.x + Root.AAR.Size.y) / 2, Root.MinSize, 0);
            tempRoot.MeshObject.Children[3] = Root.MeshObject;
        }

        Root.DestroyGameObject();
        Root = tempRoot;
        Root.ApplyValues();
    }
예제 #3
0
	/**
	 * Create a node in the quad tree.
	 *
	 * @param childType if there's a parent, the type of child
	 * @param nw        the node represent the northwest quadrant
	 * @param ne        the node represent the northeast quadrant
	 * @param sw        the node represent the southwest quadrant
	 * @param se        the node represent the southeast quadrant
	 */
	private QuadTreeNode(Quadrant quad, QuadTreeNode nw, QuadTreeNode ne, QuadTreeNode sw, QuadTreeNode se, QuadTreeNode parent)
	{
		this.quadrant = quad;
		this.nw = nw;
		this.ne = ne;
		this.sw = sw;
		this.se = se;
		this.parent = parent;
	}
예제 #4
0
 /// <summary>
 /// Create a new NBodyForce.
 /// </summary>
 /// <param name="gravConstant">the gravitational constant to use. Nodes will attract each other if this value is positive, and will repel each other if it is negative.</param>
 /// <param name="minDistance">the distance within which two particles will  interact. If -1, the value is treated as infinite.</param>
 /// <param name="theta">the Barnes-Hut parameter theta, which controls when an aggregated mass is used rather than drilling down to individual  item mass values.</param>
 public NBodyForce(float gravConstant, float minDistance, float theta)
 {
     parms = new float[] { gravConstant, minDistance, theta };
     minValues = new float[] { DEFAULT_MIN_GRAV_CONSTANT,
     DEFAULT_MIN_DISTANCE, DEFAULT_MIN_THETA };
     maxValues = new float[] { DEFAULT_MAX_GRAV_CONSTANT,
     DEFAULT_MAX_DISTANCE, DEFAULT_MAX_THETA };
     root = factory.GetQuadTreeNode();
 }
예제 #5
0
 public QuadTreeNode(QuadTree quadTree, QuadTreeNode parent, Vector2 position, float length, float minSize, int depth)
 {
     Active = true;
     Parent = parent;
     QuadTree = quadTree;
     Position = position;
     SideLength = length;
     MinSize = minSize;
     Depth = depth;
     AAR = new AxisAlignedRectangle(Position, SideLength * 2);
     MeshObject = new LODMeshObject(null, this, AAR, 0);
     CreateGameobject();
 }
예제 #6
0
    public void SetChildren(QuadTreeNode nodeBottomLeft, QuadTreeNode nodeTopLeft, QuadTreeNode nodeTopRight, QuadTreeNode nodeBottomRight)
    {
        Active = false;
        float halfSideLength = SideLength / 2;
        Children = new QuadTreeNode[4];
        Children[0] = nodeBottomLeft ?? CreateNode(Position + new Vector2(-halfSideLength, -halfSideLength), halfSideLength);
        Children[1] = nodeTopLeft ?? CreateNode(Position + new Vector2(-halfSideLength, halfSideLength), halfSideLength);
        Children[2] = nodeTopRight ?? CreateNode(Position + new Vector2(halfSideLength, halfSideLength), halfSideLength);
        Children[3] = nodeBottomRight ?? CreateNode(Position + new Vector2(halfSideLength, -halfSideLength), halfSideLength);

        MeshObject.SetChildren(Children[0].MeshObject, Children[1].MeshObject, Children[2].MeshObject, Children[3].MeshObject);

        DisableRenderer();

        ApplyValues();
    }
예제 #7
0
파일: QuadForm.cs 프로젝트: Banane9/Quads
        private Bitmap drawImageWithQuads(QuadTreeNode<Pixel, ColorAverage> quadTree, int spacing)
        {
            Bitmap result = new Bitmap((int)(quadTree.XMax - quadTree.XMin + spacing), (int)(quadTree.YMax - quadTree.YMin + spacing));

            using (Graphics graphics = Graphics.FromImage(result))
            {
                graphics.FillRectangle(Brushes.Black, 0, 0, result.Width, result.Height);

                foreach (var leaf in quadTree.GetLeafs())
                {
                    RgbColor rgbColor = leaf.Average.Color.ToRgb();
                    graphics.FillRectangle(new SolidBrush(Color.FromArgb(rgbColor.R, rgbColor.G, rgbColor.B)), (float)(leaf.XMin + spacing), (float)(leaf.YMin + spacing), (float)(leaf.XMax - leaf.XMin - spacing), (float)(leaf.YMax - leaf.YMin - spacing));
                }
            }

            return result;
        }
예제 #8
0
    /// <summary>
    /// 插入碰撞盒四叉树
    /// </summary>
    void InsetColliderQuadTree()
    {
        foreach (SceneColliderInfo res in ColliderInfoList)
        {
            if (!isVaildCollider(res))
            {
                continue;
            }

            Vector2 pos2D = Vector2.zero;
            pos2D.x = res.RefPos.x;
            pos2D.y = res.RefPos.z;
            QuadTreeNode p = GetQuadTreeParent(ColliderRootParent, pos2D);
            if (null != p)
            {
                QuadTreeLeaves leaf = new QuadTreeLeaves();
                leaf.m_ColliderInfo = res;
                leaf.m_Parent       = p;
                p.m_LeavesList.Add(leaf);
            }
        }
    }
예제 #9
0
    Vector3[] RetracePath(QuadTreeNode startNode, QuadTreeNode endNode)
    {
        List <QuadTreeNode> path        = new List <QuadTreeNode>();
        QuadTreeNode        currentNode = endNode;

        while (currentNode != startNode)
        {
            path.Add(currentNode);
            currentNode = currentNode.successor;
        }

        /*Vector3[] waypoints = SimplifyPath(path);
         * Array.Reverse(waypoints);*/
        path.Reverse();
        List <Vector3> waypoints = new List <Vector3>();

        foreach (QuadTreeNode n in path)
        {
            waypoints.Add(n.worldPosition);
        }
        return(waypoints.ToArray());
    }
예제 #10
0
    void ResetGraphicsBuffer(int nodeSize)
    {
        ConsumeNodeList.SetCounterValue(0);
        AppendNodeList.SetCounterValue(0);
        AppendFinalNodeList.SetCounterValue(0);

        QuadTreeNode[] nodes = new QuadTreeNode[nodeSize * nodeSize];
        int            index = 0;

        for (int i = 0; i < nodeSize; ++i)
        {
            for (int j = 0; j < nodeSize; ++j)
            {
                nodes[index].x = (uint)j;
                nodes[index].y = (uint)i;
                ++index;
            }
        }

        ConsumeNodeList.SetData(nodes);
        ConsumeNodeList.SetCounterValue((uint)nodes.Length);
    }
        private void InsertIntersectingChildNodes(Vector2 pos, float radius, QuadTreeNode ownerNode, QuadTreeNode node, ref List <QuadTreeNode> nodes)
        {
            if (!IntersectCircleRect(pos, radius, node.boundingRect))
            {
                // Stop here; if a higher node doesn't intersect, the child nodes are guarenteed not to intersect either
                return;
            }

            // Only add this node if there are entities to check against
            if (node.leaves.Count > 0)
            {
                nodes.Add(node);
            }

            if (node.subNodes.Count > 0)
            {
                foreach (QuadTreeNode subNode in node.subNodes)
                {
                    InsertIntersectingChildNodes(pos, radius, ownerNode, subNode, ref nodes);
                }
            }
        }
예제 #12
0
        public static IEnumerable <QuadTreeNode> GetLeaves(QuadTreeNode root)
        {
            var stack = new Stack <QuadTreeNode>();

            stack.Push(root);

            while (stack.Count > 0)
            {
                var parent = stack.Pop();
                foreach (var node in parent.GetNodes())
                {
                    if (node.IsLeaf())
                    {
                        yield return(node);
                    }
                    else
                    {
                        stack.Push(node);
                    }
                }
            }
        }
예제 #13
0
    /// <summary>
    /// Merges 4 nodes into their parent
    /// </summary>
    private void ShowNodeMerge(QuadTreeNode <NodeData> node, HashSet <QuadTreeNode <NodeData> > newActiveList)
    {
        if (RenderTerrain)
        {
            // If there is no mesh corresponding to this node
            if (!nodeMeshMap.ContainsKey(node))
            {
                // Create an empty mesh holder object
                CachedMeshHolder container = CreateNewBlock(node);

                // Set chunk data...?
                // ...

                // Call highest detail action...?
                // ...

                // Add the newly created mesh to the lists
                activeMeshes.Add(container);

                nodeMeshMap[node] = container;
            }

            // Show the node mesh
            nodeMeshMap[node].gameObject.SetActive(true);
        }

        // Discard children nodes
        foreach (var subNode in node.SubNodes)
        {
            DiscardNode(subNode);
        }

        // If the newActiveNodes don't already contain this node, add it
        if (!newActiveList.Contains(node))
        {
            newActiveList.Add(node);
        }
    }
예제 #14
0
    void DrawDebugLines()
    {
        Mesh           m           = new Mesh();
        List <Vector3> meshVerts   = new List <Vector3>();
        List <int>     meshIndices = new List <int>();

        //quadtree init
        QuadTreeNode <int> .Init(Vector3.zero, Vector2.one *Ground.Instance.transform.localScale.x, 0);

        for (int i = 0; i < indices.Length - 2; i += 3)
        {
            var i0 = indices[i];
            var i1 = indices[i + 1];
            var i2 = indices[i + 2];

            var v0 = vertices[i0];
            var v1 = vertices[i1];
            var v2 = vertices[i2];

            LineDrawerMgr.DrawLine(v0, v1);
            LineDrawerMgr.DrawLine(v1, v2);
            LineDrawerMgr.DrawLine(v2, v0);

            QuadTreeNode <int> .Root.Insert(v0, i);

            if (i == 0)
            {
                meshVerts.Add(v0);
                meshVerts.Add(v1);
                meshVerts.Add(v2);
                meshIndices.Add(i0);
                meshIndices.Add(i1);
                meshIndices.Add(i2);
            }
        }

        CommonUtils.DrawLine(v2, v1);
    }
예제 #15
0
    void ClearQuadTree(QuadTreeNode rootNode)
    {
        if (null == rootNode)
        {
            return;
        }
        //已经到子节点了
        if (rootNode.ChildCount <= 0)
        {
            foreach (QuadTreeLeaves leaf in rootNode.m_LeavesList)
            {
                leaf.m_LightInfo = null;
                leaf.m_ResInfo   = null;
            }
            rootNode.m_LeavesList.Clear();
        }

        //继续遍历剩下的结点
        foreach (QuadTreeNode p in rootNode.ChildNode)
        {
            ClearQuadTree(p);
        }
    }
예제 #16
0
            /// <summary>
            /// Creates a new object that is a copy of the current instance.
            /// </summary>
            /// <returns>A new object that is a copy of this instance</returns>
            public object Clone()
            {
                QuadTreeNode result = new QuadTreeNode(this._owner, this._fullRectangle);

                result._position = this._position;
                result._parent   = this._parent;

                foreach (IIndexable s in _objects)
                {
                    result._objects.Add((IIndexable)s.Clone());
                }

                if (HasChildren)
                {
                    if (_leftUpChild != null)
                    {
                        result._leftUpChild = (QuadTreeNode)this._leftUpChild.Clone();
                    }

                    if (_rightUpChild != null)
                    {
                        result._rightUpChild = (QuadTreeNode)this._rightUpChild.Clone();
                    }

                    if (_rightDownChild != null)
                    {
                        result._rightDownChild = (QuadTreeNode)this._rightDownChild.Clone();
                    }

                    if (_leftDownChild != null)
                    {
                        result._leftDownChild = (QuadTreeNode)this._leftDownChild.Clone();
                    }
                }

                return(result);
            }
예제 #17
0
    /**
     * Create an image which is represented using a QuadTreeNode.
     *
     * @param size      size of image
     * @param center_x  x coordinate of center
     * @param center_y; y coordinate of center
     * @param parent    parent quad tree node
     * @param quadrant  the quadrant that the sub tree is in
     * @param level     the level of the tree
     */
    public static QuadTreeNode createTree(int size, int center_x, int center_y, QuadTreeNode parent, Quadrant quadrant, int level)
    {
        QuadTreeNode node;

        int intersect = checkIntersect(center_x, center_y, size);

        size = size / 2;
        if (intersect == 0 && size < 512)
        {
            node = new WhiteNode(quadrant, parent);
        }
        else if (intersect == 2)
        {
            node = new BlackNode(quadrant, parent);
        }
        else
        {
            if (level == 0)
            {
                node = new BlackNode(quadrant, parent);
            }
            else
            {
                node = new GreyNode(quadrant, parent);
                QuadTreeNode sw = createTree(size, center_x - size, center_y - size, node,
                                             Quadrant.cSouthWest, level - 1);
                QuadTreeNode se = createTree(size, center_x + size, center_y - size, node,
                                             Quadrant.cSouthEast, level - 1);
                QuadTreeNode ne = createTree(size, center_x + size, center_y + size, node,
                                             Quadrant.cNorthEast, level - 1);
                QuadTreeNode nw = createTree(size, center_x - size, center_y + size, node,
                                             Quadrant.cNorthWest, level - 1);
                node.setChildren(nw, ne, sw, se);
            }
        }
        return(node);
    }
예제 #18
0
    /// <summary>
    /// 插入总是可见的资源四叉树,与普通的分开管理
    /// </summary>
    void InsetAlwaysVisibleResQuadTree()
    {
        foreach (SceneResInfo res in ResInfoList)
        {
            if (!isVaildAlwaysVisibleRes(res))
            {
                continue;
            }
            Vector2 pos2D = Vector2.zero;
            pos2D.x = res.RefPos.x;
            pos2D.y = res.RefPos.z;

            QuadTreeNode p = GetQuadTreeParent(AlwaysVisibleResRootParent, pos2D);
            if (null != p)
            {
                QuadTreeLeaves leaf = new QuadTreeLeaves();
                res.Init(null, SceneCamera);
                leaf.m_ResInfo   = res;
                leaf.m_Parent    = p;
                res.hostTreeNode = p;
                p.m_LeavesList.Add(leaf);
            }
        }
    }
예제 #19
0
    private void Split()
    {
        if (level < maxDepth)
        {
            double midX = (extent.MaxX + extent.MinX) / 2.0;
            double midY = (extent.MaxY + extent.MinY) / 2.0;

            nodes[0] = new QuadTreeNode(new Extent(extent.MinX, midX, midY, extent.MaxY))
            {
                maxObjects = maxObjects,
                maxDepth   = this.maxDepth,
                level      = level + 1
            };

            nodes[1] = new QuadTreeNode(new Extent(midX, extent.MaxX, midY, extent.MaxY))
            {
                maxObjects = maxObjects,
                maxDepth   = this.maxDepth,
                level      = level + 1
            };

            nodes[2] = new QuadTreeNode(new Extent(extent.MinX, midX, extent.MinY, midY))
            {
                maxObjects = maxObjects,
                maxDepth   = this.maxDepth,
                level      = level + 1
            };

            nodes[3] = new QuadTreeNode(new Extent(midX, extent.MaxX, extent.MinY, midY))
            {
                maxObjects = maxObjects,
                maxDepth   = this.maxDepth,
                level      = level + 1
            };
        }
    }
예제 #20
0
    /**
     * The entry point to computing the perimeter of an image.
     *
     * @param args the command line arguments
     */
    public static void Main(String[] args)
    {
        parseCmdLine(args);
        Quadrant.staticInitQuadrant();

        int size  = 1 << levels;
        int msize = 1 << (levels - 1);

        QuadTreeNode.gcmp = size * 1024;
        QuadTreeNode.lcmp = msize * 1024;

        QuadTreeNode tree = QuadTreeNode.createTree(msize, 0, 0, null, Quadrant.cSouthEast, levels);

        int leaves = tree.countTree();
        int perm   = tree.perimeter(size);

        if (printResult)
        {
            Console.WriteLine("Perimeter is " + perm);
            Console.WriteLine("Number of leaves " + leaves);
        }

        Console.WriteLine("Done!");
    }
예제 #21
0
    void Start()
    {
        if (ReplaySimulationFromFile)
        {
            LoadSimulationData();
        }

        simulationSofteningLengthSquared =
            SimulationSofteningLength * SimulationSofteningLength;

        WireframeController[] wireframeControllers =
            FindObjectsOfType <WireframeController> ();

        foreach (var wireframeController in wireframeControllers)
        {
            wireframeController.Planets =
                planets;
        }

        quadtree =
            new QuadTreeNode(UniverseSize);

        SetupSimulationTime();
    }
예제 #22
0
            /// <summary>
            /// Launchs foliage population asynchronous task
            /// </summary>
            /// <param name="scene">Scene</param>
            /// <param name="node">Foliage Node</param>
            /// <param name="map">Foliage map</param>
            /// <param name="description">Terrain vegetation description</param>
            /// <param name="gbbox">Relative bounding box to plant</param>
            /// <param name="delay">Task delay</param>
            public void Plant(Scene scene, QuadTreeNode node, FoliageMap map, FoliageMapChannel description, BoundingBox gbbox, int delay)
            {
                if (!this.Planting)
                {
                    //Start planting task
                    this.CurrentNode = node;
                    this.Channel     = description.Index;
                    this.Planting    = true;

                    Task
                    .Run(async() =>
                    {
                        await Task.Delay(delay);

                        return(PlantTask(scene, node, map, description, gbbox));
                    })
                    .ContinueWith((t) =>
                    {
                        this.Planting    = false;
                        this.Planted     = true;
                        this.foliageData = t.Result;
                    });
                }
            }
예제 #23
0
    /// <summary>
    /// Get the child Quad that would contain an object.
    /// </summary>
    /// <param name="item">The object to get a child for.</param>
    /// <returns></returns>
    private QuadTreeNode <T> GetDestinationTree(QuadTreeObject <T> item)
    {
        // If a child can't contain an object, it will live in this Quad
        QuadTreeNode <T> destTree = this;

        if (childTL.QuadRect.Contains(item.Data.Rect))
        {
            destTree = childTL;
        }
        else if (childTR.QuadRect.Contains(item.Data.Rect))
        {
            destTree = childTR;
        }
        else if (childBL.QuadRect.Contains(item.Data.Rect))
        {
            destTree = childBL;
        }
        else if (childBR.QuadRect.Contains(item.Data.Rect))
        {
            destTree = childBR;
        }

        return(destTree);
    }
        public IEnumerator <T> GetEnumerator()
        {
            Stack <QuadTreeNode> stack   = new Stack <QuadTreeNode>();
            QuadTreeNode         current = m_root;

            while (current != null)
            {
                if (current.Children != null)
                {
                    stack.Push(current.Children[2]);
                    stack.Push(current.Children[1]);
                    stack.Push(current.Children[3]);
                    stack.Push(current.Children[0]);
                }
                else
                {
                    QuadTreeLeaf node = current.Data;

                    while (node != null)
                    {
                        yield return(node.Data);

                        node = node.Next;
                    }
                }

                if (stack.Count > 0)
                {
                    current = stack.Pop();
                }
                else
                {
                    break;
                }
            }
        }
예제 #25
0
    public void Refresh(QuadTreeNode <T> root)
    {
        for (int i = 0; i < mDataList.Count;)
        {
            QuadTreeNode <T> nextNode = GetNode(mDataList[i].mRect);
            if (nextNode == null)
            {
                root.Insert(mDataList[i]);
                mDataList.RemoveAt(i);
            }
            else
            {
                i++;
            }
        }

        if (mNodeList != null)
        {
            for (int i = 0; i < mNodeList.Length; i++)
            {
                mNodeList[i].Refresh(root);
            }
        }
    }
예제 #26
0
    Vector3[] RetracePath(QuadTreeNode startNode, QuadTreeNode endNode)
    {
        List<QuadTreeNode> path = new List<QuadTreeNode>();
        QuadTreeNode currentNode = endNode;

        while (currentNode != startNode)
        {
            path.Add(currentNode);
            currentNode = currentNode.successor;
        }
        /*Vector3[] waypoints = SimplifyPath(path);
        Array.Reverse(waypoints);*/
        path.Reverse();
        List<Vector3> waypoints = new List<Vector3>();
        foreach (QuadTreeNode n in path)
        {
            waypoints.Add(n.worldPosition);
        }
        return waypoints.ToArray();
    }
예제 #27
0
        /// <summary>
        /// Returns the smallest quadtree at depth zero.
        /// </summary>
        /// <param name="point"></param>
        /// <returns></returns>
        private QuadTreeNode GetOrCreateAt(TPointType point)
        {
            if (_root == null)
            { // create a default root.
                _root = new QuadTreeNode(0,
                                         point[0] - 0.01, point[1] - 0.01, point[0] + 0.01, point[1] + 0.01);
            }

            if (!_root.IsInsideBox(point))
            {     // the point is inside.
                if (point[0] < _root.Min0)
                { // expand towards the minimum.
                    // descide to the minimum or maximum.
                    if (point[1] < _root.Min1)
                    { // expand towards the minimum.
                        _root = new QuadTreeNode(true, true,
                                                 _root);

                        // recursive call to the quad tree.
                        return(this.GetOrCreateAt(point));
                    }
                    else
                    { // expand towards the maximum.
                        _root = new QuadTreeNode(true, false,
                                                 _root);

                        // recursive call to the quad tree.
                        return(this.GetOrCreateAt(point));
                    }
                }
                if (point[0] > _root.Max0)
                { // expand towards the maximum.
                    // descide to the minimum or maximum.
                    if (point[1] < _root.Min1)
                    { // expand towards the minimum.
                        _root = new QuadTreeNode(false, true,
                                                 _root);

                        // recursive call to the quad tree.
                        return(this.GetOrCreateAt(point));
                    }
                    else
                    { // expand towards the maximum.
                        _root = new QuadTreeNode(false, false,
                                                 _root);

                        // recursive call to the quad tree.
                        return(this.GetOrCreateAt(point));
                    }
                }
                if (point[1] < _root.Min1)
                { // expand towards the minimum.
                    // expand towards the maximum.
                    _root = new QuadTreeNode(false, true,
                                             _root);

                    // recursive call to the quad tree.
                    return(this.GetOrCreateAt(point));
                }
                if (point[1] > _root.Max1)
                { // expand towards the maximum.// expand towards the maximum.
                    _root = new QuadTreeNode(false, false,
                                             _root);

                    // recursive call to the quad tree.
                    return(this.GetOrCreateAt(point));
                }
                throw new Exception("The point is not in the route but not outside of any bound!?");
            }
            return(_root.GetOrCreateAt(point));
        }
예제 #28
0
 /// <summary>
 /// Creates a new quad tree.
 /// </summary>
 /// <param name="dept"></param>
 /// <param name="bounds"></param>
 /// <returns></returns>
 public QuadTree(
     int dept, BoxF2D bounds)
 {
     _root = new QuadTreeNode(dept, bounds);
 }
예제 #29
0
            /// <summary>
            /// Creates a quad tree with given bounds.
            /// </summary>
            /// <param name="min0"></param>
            /// <param name="min1"></param>
            /// <param name="node"></param>
            public QuadTreeNode(bool min0, bool min1,
                                QuadTreeNode node)
            {
                _depth = node.Depth + 1;

                double min_0, max_0, min_1, max_1;

                double diff_0 = node.Max0 - node.Min0;
                double diff_1 = node.Max1 - node.Min1;

                if (min0)
                {
                    min_0 = node.Min0 - diff_0;
                    max_0 = node.Max0;

                    if (min1)
                    {
                        min_1 = node.Min1 - diff_1;
                        max_1 = node.Max1;

                        _maxMax = node;
                    }
                    else
                    {
                        min_1 = node.Min1;
                        max_1 = node.Max1 + diff_1;

                        _maxMin = node;
                    }
                }
                else
                {
                    if (min1)
                    {
                        min_1 = node.Min1 - diff_1;
                        max_1 = node.Max1;

                        _minMax = node;
                    }
                    else
                    {
                        min_1 = node.Min1;
                        max_1 = node.Max1 + diff_1;

                        _minMin = node;
                    }
                    min_0 = node.Min0;
                    max_0 = node.Max0 + diff_0;
                }

                // calculate the middles.
                _middle0 = (min_0 + max_0) / 2.0;
                _middle1 = (min_1 + max_1) / 2.0;

                _bounds = new BoxF2D(new PointF2D(max_0, max_1),
                                     new PointF2D(min_0, min_1));

                if (_depth == 0)
                {
                    _data = new List <KeyValuePair <TPointType, TDataType> >();
                }
            }
예제 #30
0
 public QuadTreeNode() {
   com = new float[] { 0.0f, 0.0f };
   children = new QuadTreeNode[4];
 } //
예제 #31
0
 /// <summary>
 /// Calculates the mass.
 /// </summary>
 /// <param name="n">The n.</param>
 private void CalculateMass(QuadTreeNode n) {
   float xcom = 0, ycom = 0;
   n.mass = 0;
   if (n.hasChildren) {
     for (int i = 0; i < n.children.Length; i++) {
       if (n.children[i] != null) {
         CalculateMass(n.children[i]);
         n.mass += n.children[i].mass;
         xcom += n.children[i].mass * n.children[i].com[0];
         ycom += n.children[i].mass * n.children[i].com[1];
       }
     }
   }
   if (n.value != null) {
     n.mass += n.value.Mass;
     xcom += n.value.Mass * n.value.Location[0];
     ycom += n.value.Mass * n.value.Location[1];
   }
   n.com[0] = xcom / n.mass;
   n.com[1] = ycom / n.mass;
 }
예제 #32
0
            private QuadTreeNode GetItemContainerNode(ref Rect bounds)
            {
                double halfWidth  = _Bounds.Width / 2;
                double halfHeight = _Bounds.Height / 2;

                QuadTreeNode child = null;

                if (_TopLeftNode == null)
                {
                    Rect topLeftRect = new Rect(_Bounds.X, _Bounds.Y, halfWidth, halfHeight);

                    if (topLeftRect.Contains(bounds))
                    {
                        _TopLeftNode = new QuadTreeNode(topLeftRect);
                        child        = _TopLeftNode;
                    }
                }
                else if (_TopLeftNode._Bounds.Contains(bounds))
                {
                    child = _TopLeftNode;
                }

                if (child == null)
                {
                    if (_TopRightNode == null)
                    {
                        Rect topRightRect = new Rect(_Bounds.X + halfWidth, _Bounds.Y, halfWidth, halfHeight);

                        if (topRightRect.Contains(bounds))
                        {
                            _TopRightNode = new QuadTreeNode(topRightRect);
                            child         = _TopRightNode;
                        }
                    }
                    else if (_TopRightNode._Bounds.Contains(bounds))
                    {
                        child = _TopRightNode;
                    }
                }

                if (child == null)
                {
                    if (_BottomRightNode == null)
                    {
                        Rect bottomRightRect = new Rect(_Bounds.X + halfWidth, _Bounds.Y + halfHeight, halfWidth, halfHeight);

                        if (bottomRightRect.Contains(bounds))
                        {
                            _BottomRightNode = new QuadTreeNode(bottomRightRect);
                            child            = _BottomRightNode;
                        }
                    }
                    else if (_BottomRightNode._Bounds.Contains(bounds))
                    {
                        child = _BottomRightNode;
                    }
                }

                if (child == null)
                {
                    if (_BottomLeftNode == null)
                    {
                        Rect bottomLeftRect = new Rect(_Bounds.X, _Bounds.Y + halfHeight, halfWidth, halfHeight);

                        if (bottomLeftRect.Contains(bounds))
                        {
                            _BottomLeftNode = new QuadTreeNode(bottomLeftRect);
                            child           = _BottomLeftNode;
                        }
                    }
                    else if (_BottomLeftNode._Bounds.Contains(bounds))
                    {
                        child = _BottomLeftNode;
                    }
                }
                return(child);
            }
예제 #33
0
	/**
	 * Return the child that represents this quadrant of the given
	 * node.
	 *
	 * @param node the node that we want the child from.
	 * @return the child node representing this quadrant
	 */
	abstract public QuadTreeNode child(QuadTreeNode node);
예제 #34
0
 public void Initialize(Vector2 minCorner, Vector2 maxCorner)
 {
     root = null;
     root = new QuadTreeNode(minCorner, maxCorner, 0);
 }
예제 #35
0
 public void Start()
 {
     Noise = new SimplexNoise();
     Noise.Initialize();
     Root = new QuadTreeNode(this, null, Vector2.zero, Helper.ViewDistance, 4, 0);
 }
예제 #36
0
		/**
	 * Return the child that represents this quadrant of the given
	 * node.
	 *
	 * @param node the node that we want the child from.
	 * @return the child node representing this quadrant
	 */
		public override QuadTreeNode child (QuadTreeNode node)
		{
			return node.getSouthWest ();
		}
 static void GizmosDrawNode(QuadTreeNode<KRTransform> n)
 {
     Gizmos.color = n.IsFree() ? Color.blue : Color.green;
     Vector3 p0 = n.BottomLeft.ToVector3(), p1 = n.TopRight.ToVector3();
     Gizmos.DrawLine(p0, p0 + new Vector3(n.Width-.2f, 0, .1f));
     Gizmos.DrawLine(p0, p0 + new Vector3(.1f, 0, n.Height-.2f));
     Gizmos.DrawLine(p1, p1 - new Vector3(n.Width-.2f, 0, .1f));
     Gizmos.DrawLine(p1, p1 - new Vector3(.1f, 0, n.Height-.2f));
 }
예제 #38
0
		/**
	 * Construct a <tt>black</tt> quad tree node.
	 *
	 * @param quadrant the quadrant that this node represents
	 * @param the      parent quad tree node
	 */
		public BlackNode (Quadrant quadrant, QuadTreeNode parent)
			: base (quadrant, parent)
		{
			;
		}
예제 #39
0
        private static int FindNextMerge(List <PathDefWithClosed> Paths, out int highestnomatch, int startat = 0)
        {
            highestnomatch = 0;
            QuadTreeNode Root = new QuadTreeNode();

            PolyLineSet.Bounds B = new PolyLineSet.Bounds();
            for (int i = startat; i < Paths.Count; i++)
            {
                if (Paths[i].Closed == false)
                {
                    B.FitPoint(Paths[i].Vertices.First());
                    B.FitPoint(Paths[i].Vertices.Last());
                }
            }

            Root.xstart = B.TopLeft.X - 10;
            Root.xend   = B.BottomRight.X + 10;
            Root.ystart = B.TopLeft.Y - 10;
            Root.yend   = B.BottomRight.Y + 10;

            for (int i = startat; i < Paths.Count; i++)
            {
                if (Paths[i].Closed == false)
                {
                    Root.Insert(new SegmentEndContainer()
                    {
                        PathID = i, Point = Paths[i].Vertices.First(), Side = SideEnum.Start
                    }, 4);
                    Root.Insert(new SegmentEndContainer()
                    {
                        PathID = i, Point = Paths[i].Vertices.Last(), Side = SideEnum.End
                    }, 4);
                }
            }
            RectangleF R = new RectangleF();

            R.Width  = 10;
            R.Height = 10;

            for (int i = startat; i < Paths.Count; i++)
            {
                //     Console.WriteLine("checking path {0}", i);
                var P = Paths[i];
                if (P.Closed == false)
                {
                    var PF = P.Vertices.First();
                    //  Console.WriteLine("checking firstvert {0}", PF);

                    R.X = (float)(P.Vertices.First().X - 5);
                    R.Y = (float)(P.Vertices.First().Y - 5);
                    int startmatch = -1;
                    int endmatch   = -1;
                    Root.CallBackInside(R, delegate(QuadTreeItem QI)
                    {
                        var S = QI as SegmentEndContainer;
                        if (S.PathID == i)
                        {
                            return(true);
                        }
                        //   Console.WriteLine(" against {0}", S.Point);
                        if (S.Point == PF)
                        {
                            if (S.Side == SideEnum.Start)
                            {
                                startmatch = S.PathID;
                                //    Console.WriteLine(" matched start {0}" , startmatch);
                            }
                            else
                            {
                                endmatch = S.PathID;
                                //    Console.WriteLine(" matched end {0}", endmatch);
                            }
                        }
                        return(true);
                    });

                    if (startmatch > -1 || endmatch > -1)
                    {
                        if (endmatch > -1)
                        {
                            Paths[endmatch].Vertices.Remove(Paths[endmatch].Vertices.Last());
                            Paths[endmatch].Vertices.AddRange(Paths[i].Vertices);
                            if (Paths[endmatch].Vertices.First() == Paths[endmatch].Vertices.Last())
                            {
                                Console.WriteLine("closed path with {0} points during stage 3a", Paths[endmatch].Vertices.Count());
                                Paths[endmatch].Closed = true;
                            }
                            Paths.Remove(Paths[i]);
                            //Console.WriteLine(" a");
                            return(1);
                        }
                        if (startmatch > -1)
                        {
                            Paths[i].Vertices.Reverse();
                            Paths[i].Vertices.Remove(Paths[i].Vertices.Last());
                            Paths[i].Vertices.AddRange(Paths[startmatch].Vertices);
                            if (Paths[i].Vertices.First() == Paths[i].Vertices.Last())
                            {
                                Console.WriteLine("closed path with {0} points during stage 3b", Paths[i].Vertices.Count());
                                Paths[i].Closed = true;
                            }
                            Paths.Remove(Paths[startmatch]);
                            //  Console.WriteLine(" b");

                            return(1);
                        }
                    }

                    PF = P.Vertices.Last();
                    // Console.WriteLine("checking lastvert {0}", PF);
                    R.X        = (float)(P.Vertices.First().X - 5);
                    R.Y        = (float)(P.Vertices.First().Y - 5);
                    startmatch = -1;
                    endmatch   = -1;
                    Root.CallBackInside(R, delegate(QuadTreeItem QI)
                    {
                        var S = QI as SegmentEndContainer;
                        if (S.PathID == i)
                        {
                            return(true);
                        }
                        //  Console.WriteLine(" against {0}", S.Point);

                        if (S.Point == PF)
                        {
                            if (S.Side == SideEnum.Start)
                            {
                                startmatch = S.PathID;
                            }
                            else
                            {
                                endmatch = S.PathID;
                            }
                        }
                        return(true);
                    });

                    if (startmatch > -1 || endmatch > -1)
                    {
                        if (endmatch > -1)
                        {
                            Paths[i].Vertices.Reverse();
                            Paths[endmatch].Vertices.Remove(Paths[endmatch].Vertices.Last());
                            Paths[endmatch].Vertices.AddRange(Paths[i].Vertices);
                            if (Paths[endmatch].Vertices.First() == Paths[endmatch].Vertices.Last())
                            {
                                Console.WriteLine("closed path with {0} points during stage 3c", Paths[endmatch].Vertices.Count());
                                Paths[endmatch].Closed = true;
                            }
                            Paths.Remove(Paths[i]);
                            //Console.WriteLine(" c");

                            return(1);
                        }
                        if (startmatch > -1)
                        {
                            Paths[i].Vertices.Remove(Paths[i].Vertices.Last());
                            Paths[i].Vertices.AddRange(Paths[startmatch].Vertices);
                            if (Paths[i].Vertices.First() == Paths[i].Vertices.Last())
                            {
                                Console.WriteLine("closed path with {0} points during stage 3d", Paths[i].Vertices.Count());
                                Paths[i].Closed = true;
                            }
                            Paths.Remove(Paths[startmatch]);
                            //Console.WriteLine(" d");

                            return(1);
                        }
                    }

                    highestnomatch = i;
                }
            }

            return(0);
            //for (int i = 0; i < Paths.Count; i++)
            //{
            //    for (int j = i + 1; j < Paths.Count; j++)
            //    {
            //        if (Paths[i].Closed == false && Paths[j].Closed == false)
            //        {
            //            if (Paths[j].Vertices.First() == Paths[i].Vertices.Last())
            //            {
            //                Paths[i].Vertices.Remove(Paths[i].Vertices.Last());
            //                Paths[i].Vertices.AddRange(Paths[j].Vertices);
            //                if (Paths[i].Vertices.First() == Paths[i].Vertices.Last()) Paths[i].Closed = true;
            //                Paths.Remove(Paths[j]);
            //                return 1;
            //            }
            //            else
            //            {
            //                if (Paths[i].Vertices.First() == Paths[j].Vertices.Last())
            //                {
            //                    Paths[j].Vertices.Remove(Paths[j].Vertices.Last());
            //                    Paths[j].Vertices.AddRange(Paths[i].Vertices);
            //                    if (Paths[j].Vertices.First() == Paths[j].Vertices.Last()) Paths[j].Closed = true;
            //                    Paths.Remove(Paths[i]);
            //                    return 1;

            //                }
            //                else
            //                {
            //                    if (Paths[i].Vertices.First() == Paths[j].Vertices.First())
            //                    {
            //                        Paths[i].Vertices.Reverse();
            //                        Paths[i].Vertices.Remove(Paths[i].Vertices.Last());
            //                        Paths[i].Vertices.AddRange(Paths[j].Vertices);
            //                        if (Paths[i].Vertices.First() == Paths[i].Vertices.Last()) Paths[i].Closed = true;
            //                        Paths.Remove(Paths[j]);
            //                        return 1;

            //                    }
            //                    else
            //                        if (Paths[i].Vertices.Last() == Paths[j].Vertices.Last())
            //                    {
            //                        Paths[i].Vertices.Reverse();
            //                        Paths[j].Vertices.Remove(Paths[j].Vertices.Last());
            //                        Paths[j].Vertices.AddRange(Paths[i].Vertices);
            //                        if (Paths[j].Vertices.First() == Paths[j].Vertices.Last()) Paths[j].Closed = true;
            //                        Paths.Remove(Paths[i]);
            //                        return 1;

            //                    }
            //                }
            //            }
            //        }
            //    }
            //}

            //return 0;
        }
예제 #40
0
    // Update is called once per frame
    void Update()
    {
        Camera cam = GetComponent<Camera>();

        //Vector3 screen_coords = cam.WorldToScreenPoint(some_cube.transform.position);
        TextureDraw.ClearTexture(tex);

        //set everything to false
        for(int i = 0; i<  resolution; i++)
        {
            for(int j = 0; j<  resolution; j++)
            {
                bool_values[i, j] =  false;

            }
        }

        quadtree_for_this_update = new QuadTreeNode(new Rect(0,0,Screen.width,Screen.height), bool_values, cubes, quadtree_max_depth, 1);
        determine_terrain_data();
        draw_marched_squares();
        //draw_cubes();
        tex.Apply();
    }
예제 #41
0
	/**
	 * Create an image which is represented using a QuadTreeNode.
	 *
	 * @param size      size of image
	 * @param center_x  x coordinate of center
	 * @param center_y; y coordinate of center
	 * @param parent    parent quad tree node
	 * @param quadrant  the quadrant that the sub tree is in
	 * @param level     the level of the tree
	 */
	public static QuadTreeNode createTree(int size, int center_x, int center_y, QuadTreeNode parent, Quadrant quadrant, int level)
	{
		QuadTreeNode node;

		int intersect = checkIntersect(center_x, center_y, size);
		size = size / 2;
		if(intersect == 0 && size < 512)
		{
			node = new WhiteNode(quadrant, parent);
		}
		else if(intersect == 2)
		{
			node = new BlackNode(quadrant, parent);
		}
		else
		{
			if(level == 0)
			{
				node = new BlackNode(quadrant, parent);
			}
			else
			{
				node = new GreyNode(quadrant, parent);
				QuadTreeNode sw = createTree(size, center_x - size, center_y - size, node,
					Quadrant.cSouthWest, level - 1);
				QuadTreeNode se = createTree(size, center_x + size, center_y - size, node,
					Quadrant.cSouthEast, level - 1);
				QuadTreeNode ne = createTree(size, center_x + size, center_y + size, node,
					Quadrant.cNorthEast, level - 1);
				QuadTreeNode nw = createTree(size, center_x - size, center_y + size, node,
					Quadrant.cNorthWest, level - 1);
				node.setChildren(nw, ne, sw, se);
			}
		}
		return node;
	}
예제 #42
0
	/**
	 * Create a leaf node in the Quad Tree.
	 *
	 * @param childType if there's a parent, the type of child this node represents
	 * @param parent    the parent quad tree node
	 */
	public QuadTreeNode(Quadrant quad, QuadTreeNode parent)
		: this(quad, null, null, null, null, parent)
	{ ;}
예제 #43
0
    /// <summary>
    /// Utility method.
    /// </summary>
    /// <param name="item">The item.</param>
    /// <param name="n">The n.</param>
    /// <param name="x1">The x1.</param>
    /// <param name="y1">The y1.</param>
    /// <param name="x2">The x2.</param>
    /// <param name="y2">The y2.</param>
    private void ForceHelper(ForceItem item, QuadTreeNode n, float x1, float y1, float x2, float y2) {
      float dx = n.com[0] - item.Location[0];
      float dy = n.com[1] - item.Location[1];
      float r = (float)Math.Sqrt(dx * dx + dy * dy);
      bool same = false;
      if (r == 0.0f) {
        // if items are in the exact same place, add some noise
        dx = Convert.ToSingle((rand.NextDouble() - 0.5D) / 50.0D);
        dy = Convert.ToSingle((rand.NextDouble() - 0.5D) / 50.0D);
        r = (float)Math.Sqrt(dx * dx + dy * dy);
        same = true;
      }
      bool minDist = parms[MIN_DISTANCE] > 0f && r > parms[MIN_DISTANCE];

      // the Barnes-Hut approximation criteria is if the ratio of the
      // size of the quadtree box to the distance between the point and
      // the box's center of mass is beneath some threshold theta.
      if ((!n.hasChildren && n.value != item) ||
           (!same && (x2 - x1) / r < parms[BARNES_HUT_THETA])) {
        if (minDist) return;
        // either only 1 particle or we meet criteria
        // for Barnes-Hut approximation, so calc force
        float v = parms[GRAVITATIONAL_CONST] * item.Mass * n.mass
                    / (r * r * r);
        item.Force[0] += v * dx;
        item.Force[1] += v * dy;
      } else if (n.hasChildren) {
        // recurse for more accurate calculation
        float splitx = (x1 + x2) / 2;
        float splity = (y1 + y2) / 2;
        for (int i = 0; i < n.children.Length; i++) {
          if (n.children != null && n.children[i] != null) {
            ForceHelper(item, n.children[i],
                (i == 1 || i == 3 ? splitx : x1), (i > 1 ? splity : y1),
                (i == 1 || i == 3 ? x2 : splitx), (i > 1 ? y2 : splity));
          }
        }
        if (minDist) return;
        if (n.value != null && n.value != item) {
          float v = parms[GRAVITATIONAL_CONST] * item.Mass * n.value.Mass
                      / (r * r * r);
          item.Force[0] += v * dx;
          item.Force[1] += v * dy;
        }
      }
    }
예제 #44
0
        public void Render(TerrainTile tile, TerrainGlobal terrainGlobal, Matrix4 projection, Matrix4 view, Vector3 eye)
        {
            Vector3 xformeye = Vector4.Transform(new Vector4(eye, 0.0f), tile.InverseModelMatrix).Xyz;

            // construct our top-level quadtree node
            var root = new QuadTreeNode()
            {
                TopLeft = new QuadTreeVertex()
                {
                    Position = new Vector3(0f, 0f, 0f)
                    //Position = Vector3.Transform(new Vector3(0f, 0f, 0f), tile.ModelMatrix)
                },
                TopRight = new QuadTreeVertex()
                {
                    Position = new Vector3((float)tile.Width, 0f, 0f)
                    //Position = Vector3.Transform(new Vector3((float)tile.Width, 0f, 0f), tile.ModelMatrix)
                },
                BottomLeft = new QuadTreeVertex()
                {
                    Position = new Vector3(0f, 0f, (float)tile.Height)
                    //Position = Vector3.Transform(new Vector3(0f, 0f, (float)tile.Height), tile.ModelMatrix)
                },
                BottomRight = new QuadTreeVertex()
                {
                    Position = new Vector3((float)tile.Width, 0f, (float)tile.Height)
                    //Position = Vector3.Transform(new Vector3((float)tile.Width, 0f, (float)tile.Height), tile.ModelMatrix)
                },
                TileSize = tile.Width // assume width == height
            };

            // check to see if we're completely outside the far detail radius
            if (!root.IsViewerInDetailRange(xformeye, this.DistantTileRadius))
            {
                var distrenderer = (IPatchRenderer)fullTileDistantRenderer;

                //float distancepastdetail = (xformeye.Xz - new Vector2((float)tile.Width * 0.5f,(float)tile.Height * 0.5f)).Length - ;

                distrenderer.Width = tile.Width / 16;
                distrenderer.Height = distrenderer.Width;
                //distrenderer.DetailScale = (float)this.TileSize / (float)tileDetailRenderer.Width;
                distrenderer.Scale = 1.0f;
                distrenderer.Offset = new Vector2(0.0f, 0.0f);

                fullTileDistantRenderer.Render(tile, terrainGlobal, projection, view, eye);
            }
            else // check inner detail radius
            {
                if (!root.IsViewerInDetailRange(xformeye, this.DetailRadius))
                {
                    // HACK because we're using the same patch renderer as the detail patches and it keeps state
                    (fullTileNearRenderer as IPatchRenderer).Scale = 1.0f;
                    (fullTileNearRenderer as IPatchRenderer).Offset = Vector2.Zero;
                    (fullTileNearRenderer as IPatchRenderer).Width = tile.Width;
                    (fullTileNearRenderer as IPatchRenderer).Height = tile.Height;

                    fullTileNearRenderer.Render(tile, terrainGlobal, projection, view, eye);
                }
                else
                {
                    root.Render(tile, terrainGlobal, projection, view, eye, xformeye, this.DetailRadius, this.subTileRenderer, this.subTileDetailRenderer);
                }
            }
        }
예제 #45
0
 /// <summary>
 /// Reclaims the specified node.
 /// </summary>
 /// <param name="n">The n.</param>
 public void Reclaim(QuadTreeNode n) {
   n.mass = 0;
   n.com[0] = 0.0f; n.com[1] = 0.0f;
   n.value = null;
   n.hasChildren = false;
   for (int i = 0; i < n.children.Length; i++) {
     n.children[i] = null;
   }
   //n.children = null;
   if (nodes.Count < maxNodes)
     nodes.Add(n);
 }
예제 #46
0
	/**
	 * Set the children of the quad tree node.
	 *
	 * @param nw the node represent the northwest quadrant
	 * @param ne the node represent the northeast quadrant
	 * @param sw the node represent the southwest quadrant
	 * @param se the node represent the southeast quadrant
	 */
	public void setChildren(QuadTreeNode nw, QuadTreeNode ne, QuadTreeNode sw, QuadTreeNode se)
	{
		this.nw = nw;
		this.ne = ne;
		this.sw = sw;
		this.se = se;
	}
예제 #47
0
 /// <summary>
 /// Creates a rootless quad tree.
 /// </summary>
 public QuadTree()
 {
     _root = null;
 }
        public void QueryNode(QuadTreeNode node, ObjectArray<QuadTreeNode> results, IndexedVector3 source,IndexedVector3 direction)
        {
            //if(node.children == null && node.Intersects(raySource,rayTarget))
            // add the lowest level.

            if (node.children == null)
            {
                results.Add(node);
#if DEBUG_ACCELERATOR
                if (BulletGlobals.gDebugDraw != null)
                {

                    IndexedVector3 drawMin = new IndexedVector3(node.boundingBox.Min);
                    IndexedVector3 drawMax = new IndexedVector3(node.boundingBox.Max);

                    IndexedVector3 worldMin = LocalToWorld2(drawMin);
                    IndexedVector3 worldMax = LocalToWorld2(drawMax);

                    BulletGlobals.gDebugDraw.DrawAabb(worldMin, worldMax, new IndexedVector3(1, 1, 1));
                }
#endif
            }
            else
            {


                // simple rescursive for now.
                for (int i = 0; i < 4; ++i)
                {
                    if (node.children[i].Intersects(source,direction))
                    {
                        QueryNode(node.children[i], results, source,direction);
                    }
                }
            }
        }
예제 #49
0
 /// <summary>
 /// Creates a new quad tree.
 /// </summary>
 /// <param name="dept"></param>
 /// <param name="min0"></param>
 /// <param name="min1"></param>
 /// <param name="max0"></param>
 /// <param name="max1"></param>
 /// <returns></returns>
 public QuadTree(
     int dept, double min0, double min1, double max0, double max1)
 {
     _root = new QuadTreeNode(dept, min0, min1, max0, max1);
 }
예제 #50
0
		/**
	 * Return the child that represents this quadrant of the given
	 * node.
	 *
	 * @param node the node that we want the child from.
	 * @return the child node representing this quadrant
	 */
		public override QuadTreeNode child (QuadTreeNode node)
		{
			return node.getNorthEast ();
		}
예제 #51
0
 /**
  * Return the child that represents this quadrant of the given
  * node.
  *
  * @param node the node that we want the child from.
  * @return the child node representing this quadrant
  */
 public override QuadTreeNode child(QuadTreeNode node)
 {
     return(node.getSouthWest());
 }
예제 #52
0
 /// <summary>
 ///Clears the quadtree of all entries.
 /// </summary>
 public void clear() {
   ClearHelper(root);
   root = factory.GetQuadTreeNode();
 }
예제 #53
0
 public QuadTree(Rectangle argR)
 {
     firstNode  = new QuadTreeNode(argR, levels);
     allObjects = new List <T>();
 }
예제 #54
0
 /// <summary>
 /// Clearing aid
 /// </summary>
 /// <param name="n">The n.</param>
 private void ClearHelper(QuadTreeNode n) {
   for (int i = 0; i < n.children.Length; i++) {
     if (n.children[i] != null)
       ClearHelper(n.children[i]);
   }
   factory.Reclaim(n);
 }
예제 #55
0
        private static List <PathDefWithClosed> StripOverlaps(List <PathDefWithClosed> Paths)
        {
            List <PathDefWithClosed> Res  = new List <PathDefWithClosed>();
            QuadTreeNode             Root = new QuadTreeNode();

            PolyLineSet.Bounds B = new PolyLineSet.Bounds();
            for (int i = 0; i < Paths.Count; i++)
            {
                if (Paths[i].Closed == false)
                {
                    foreach (var a in Paths[i].Vertices)
                    {
                        B.FitPoint(a);
                    }
                }
                else
                {
                    Res.Add(Paths[i]);
                }
            }

            Root.xstart = B.TopLeft.X - 10;
            Root.xend   = B.BottomRight.X + 10;
            Root.ystart = B.TopLeft.Y - 10;
            Root.yend   = B.BottomRight.Y + 10;
            RectangleF QueryRect = new RectangleF();

            QueryRect.Width  = 3;
            QueryRect.Height = 3;
            List <PathDefWithClosed> ToDelete = new List <PathDefWithClosed>();

            for (int i = 0; i < Paths.Count; i++)
            {
                if (Paths[i].Closed == false)
                {
                    int nearcount = 0;
                    foreach (var a in Paths[i].Vertices)
                    {
                        QueryRect.X = (float)a.X - 1.5f;
                        QueryRect.Y = (float)a.Y - 1.5f;

                        Root.CallBackInside(QueryRect, delegate(QuadTreeItem QI)
                        {
                            var S = QI as SegmentEndContainer;
                            if (S.Point == a)
                            {
                                nearcount++;
                            }
                            else
                            {
                                if (PointD.Distance(a, S.Point) < 0.001)
                                {
                                    nearcount++;
                                }
                            }
                            return(true);
                        }
                                            );
                    }

                    int max = Math.Max(4, (Paths[i].Vertices.Count * 50) / 100);

                    if (nearcount <= max)
                    {
                        foreach (var a in Paths[i].Vertices)
                        {
                            Root.Insert(new SegmentEndContainer()
                            {
                                PathID = i, Point = a, Side = SideEnum.Start
                            }, 8);
                        }
                        Res.Add(Paths[i]);
                    }
                    else
                    {
                        Res.Add(Paths[i]);
                        Console.WriteLine("{4}: {0} out of {1}/{2}/{3}", nearcount, max, Paths[i].Vertices.Count, (Paths[i].Vertices.Count * 90) / 100, i);
                        Console.WriteLine("{0}: skipped!", i);
                    }
                }
            }
            return(Res);
        }
예제 #56
0
 /// <summary>
 /// Inserts the specified force.
 /// </summary>
 /// <param name="p">The p.</param>
 /// <param name="n">The n.</param>
 /// <param name="x1">The x1.</param>
 /// <param name="y1">The y1.</param>
 /// <param name="x2">The x2.</param>
 /// <param name="y2">The y2.</param>
 private void Insert(ForceItem p, QuadTreeNode n, float x1, float y1, float x2, float y2) {
   // try to Insert particle p at node n in the quadtree
   // by construction, each leaf will contain either 1 or 0 particles
   if (n.hasChildren) {
     // n contains more than 1 particle
     InsertHelper(p, n, x1, y1, x2, y2);
   } else if (n.value != null) {
     // n contains 1 particle
     if (IsSameLocation(n.value, p)) {
       InsertHelper(p, n, x1, y1, x2, y2);
     } else {
       ForceItem v = n.value; n.value = null;
       InsertHelper(v, n, x1, y1, x2, y2);
       InsertHelper(p, n, x1, y1, x2, y2);
     }
   } else {
     // n is empty, so is a leaf
     n.value = p;
   }
 }
예제 #57
0
        private static int FindNextClosest(List <PathDefWithClosed> Paths)
        {
            QuadTreeNode Root = new QuadTreeNode();

            PolyLineSet.Bounds B = new PolyLineSet.Bounds();
            for (int i = 0; i < Paths.Count; i++)
            {
                if (Paths[i].Closed == false)
                {
                    B.FitPoint(Paths[i].Vertices.First());
                    B.FitPoint(Paths[i].Vertices.Last());
                }
            }

            Root.xstart = B.TopLeft.X - 10;
            Root.xend   = B.BottomRight.X + 10;
            Root.ystart = B.TopLeft.Y - 10;
            Root.yend   = B.BottomRight.Y + 10;

            for (int i = 0; i < Paths.Count; i++)
            {
                if (Paths[i].Closed == false)
                {
                    Root.Insert(new SegmentEndContainer()
                    {
                        PathID = i, Point = Paths[i].Vertices.First(), Side = SideEnum.Start
                    }, 5);
                    Root.Insert(new SegmentEndContainer()
                    {
                        PathID = i, Point = Paths[i].Vertices.Last(), Side = SideEnum.End
                    }, 5);
                }
            }
            RectangleF R = new RectangleF();

            R.Width  = 3;
            R.Height = 3;

            for (int i = 0; i < Paths.Count; i++)
            {
                var P = Paths[i];
                if (P.Closed == false)
                {
                    var PF  = P.Vertices[0];
                    var PF2 = P.Vertices[1];

                    var PathDir = PF - PF2;// MathHelpers.Difference(PF, PF2);
                    PathDir.Normalize();

                    R.X = (float)(P.Vertices.First().X - 1.5);
                    R.Y = (float)(P.Vertices.First().Y - 1.5);
                    int    startmatch      = -1;
                    int    endmatch        = -1;
                    double closestdistance = B.Width() + B.Height();
                    Root.CallBackInside(R, delegate(QuadTreeItem QI)
                    {
                        var S = QI as SegmentEndContainer;
                        if (S.PathID == i)
                        {
                            return(true);
                        }
                        if (P.Width != Paths[S.PathID].Width)
                        {
                            return(true);
                        }
                        PointD Dir2;
                        if (S.Side == SideEnum.Start)
                        {
                            var S2 = Paths[S.PathID].Vertices[1];
                            Dir2   = S2 - S.Point;
                            Dir2.Normalize();
                        }
                        else
                        {
                            var S2 = Paths[S.PathID].Vertices[Paths[S.PathID].Vertices.Count() - 2];
                            Dir2   = S2 - S.Point;
                            Dir2.Normalize();
                        }

                        double dotted = Dir2.Dot(PathDir);
                        var D         = PointD.Distance(S.Point, PF);
                        if (D < 1.0)
                        {
                            //  D -= dotted * 3.0;
                            if (D < closestdistance)
                            {
                                closestdistance = D;
                                if (S.Side == SideEnum.Start)
                                {
                                    startmatch = S.PathID;
                                }
                                else
                                {
                                    endmatch = S.PathID;
                                }
                            }
                        }
                        return(true);
                    });

                    if (startmatch > -1 || endmatch > -1)
                    {
                        if (endmatch > -1)
                        {
                            if (closestdistance > 0)
                            {
                                Paths[endmatch].Vertices.Remove(Paths[endmatch].Vertices.Last());
                            }
                            Paths[endmatch].Vertices.AddRange(Paths[i].Vertices);
                            if (Paths[endmatch].Vertices.First() == Paths[endmatch].Vertices.Last())
                            {
                                Console.WriteLine("closed path with {0} points during stage 4a", Paths[endmatch].Vertices.Count());
                                Paths[endmatch].Closed = true;
                            }
                            Paths.Remove(Paths[i]);
                            // Console.WriteLine(" 4a");
                            return(1);
                        }
                        if (startmatch > -1)
                        {
                            Paths[i].Vertices.Reverse();
                            if (closestdistance > 0)
                            {
                                Paths[i].Vertices.Remove(Paths[i].Vertices.Last());
                            }
                            Paths[i].Vertices.AddRange(Paths[startmatch].Vertices);
                            if (Paths[i].Vertices.First() == Paths[i].Vertices.Last())
                            {
                                Console.WriteLine("closed path with {0} points during stage 4b", Paths[i].Vertices.Count());
                                Paths[i].Closed = true;
                            }
                            Paths.Remove(Paths[startmatch]);
                            //Console.WriteLine(" 4b");

                            return(1);
                        }
                    }

                    PF              = P.Vertices.Last();
                    R.X             = (float)(P.Vertices.First().X - 1.5);
                    R.Y             = (float)(P.Vertices.First().Y - 1.5);
                    startmatch      = -1;
                    endmatch        = -1;
                    closestdistance = B.Width() + B.Height();
                    Root.CallBackInside(R, delegate(QuadTreeItem QI)
                    {
                        var S = QI as SegmentEndContainer;
                        if (S.PathID == i)
                        {
                            return(true);
                        }
                        if (P.Width != Paths[S.PathID].Width)
                        {
                            return(true);
                        }

                        var D = PointD.Distance(S.Point, PF);
                        if (D < 1.0 && D < closestdistance)
                        {
                            closestdistance = D;
                            if (S.Side == SideEnum.Start)
                            {
                                startmatch = S.PathID;
                            }
                            else
                            {
                                endmatch = S.PathID;
                            }
                        }
                        return(true);
                    });

                    if (startmatch > -1 || endmatch > -1)
                    {
                        if (endmatch > -1)
                        {
                            Paths[i].Vertices.Reverse();
                            if (closestdistance > 0)
                            {
                                Paths[endmatch].Vertices.Remove(Paths[endmatch].Vertices.Last());
                            }
                            Paths[endmatch].Vertices.AddRange(Paths[i].Vertices);
                            if (Paths[endmatch].Vertices.First() == Paths[endmatch].Vertices.Last())
                            {
                                Console.WriteLine("closed path with {0} points during stage 4c", Paths[endmatch].Vertices.Count());
                                Paths[endmatch].Closed = true;
                            }
                            Paths.Remove(Paths[i]);
                            //  Console.WriteLine(" 4c");

                            return(1);
                        }
                        if (startmatch > -1)
                        {
                            if (closestdistance > 0)
                            {
                                Paths[i].Vertices.Remove(Paths[i].Vertices.Last());
                            }
                            Paths[i].Vertices.AddRange(Paths[startmatch].Vertices);
                            if (Paths[i].Vertices.First() == Paths[i].Vertices.Last())
                            {
                                Console.WriteLine("closed path with {0} points during stage 4d", Paths[i].Vertices.Count());
                                Paths[i].Closed = true;
                            }
                            Paths.Remove(Paths[startmatch]);
                            // Console.WriteLine(" 4d");

                            return(1);
                        }
                    }
                }
            }

            return(0);
        }
예제 #58
0
 /// <summary>
 /// Inserts helper method.
 /// </summary>
 /// <param name="p">The p.</param>
 /// <param name="n">The n.</param>
 /// <param name="x1">The x1.</param>
 /// <param name="y1">The y1.</param>
 /// <param name="x2">The x2.</param>
 /// <param name="y2">The y2.</param>
 private void InsertHelper(ForceItem p, QuadTreeNode n, float x1, float y1, float x2, float y2) {
   float x = p.Location[0], y = p.Location[1];
   float splitx = (x1 + x2) / 2;
   float splity = (y1 + y2) / 2;
   int i = (x >= splitx ? 1 : 0) + (y >= splity ? 2 : 0);
   // create new child node, if necessary
   if (n.children[i] == null) {
     n.children[i] = factory.GetQuadTreeNode();
     n.hasChildren = true;
   }
   // update bounds
   if (i == 1 || i == 3) x1 = splitx; else x2 = splitx;
   if (i > 1) y1 = splity; else y2 = splity;
   // recurse 
   Insert(p, n.children[i], x1, y1, x2, y2);
 }
 void combineNode(QuadTreeNode node) {
     /**
      * 遍历四个子象限的点,添加到象限点列表
      * 释放子象限的内存
      */
 }
예제 #60
0
	/**
	 * Construct a <tt>grey</tt> image node.
	 *
	 * @param quadrant the quadrant that this node represents
	 * @param parent   the parent node in the quad tree.
	 */
	public GreyNode(Quadrant quadrant, QuadTreeNode parent)
		: base(quadrant, parent)
	{ ;}