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 }
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(); }
/** * 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; }
/// <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(); }
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(); }
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(); }
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; }
/// <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); } } }
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()); }
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); } } }
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); } } } }
/// <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); } }
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); }
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); } }
/// <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); }
/** * 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); }
/// <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); } } }
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 }; } }
/** * 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!"); }
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(); }
/// <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; }); } }
/// <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; } } }
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); } } }
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(); }
/// <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)); }
/// <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); }
/// <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> >(); } }
public QuadTreeNode() { com = new float[] { 0.0f, 0.0f }; children = new QuadTreeNode[4]; } //
/// <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; }
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); }
/** * 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);
public void Initialize(Vector2 minCorner, Vector2 maxCorner) { root = null; root = new QuadTreeNode(minCorner, maxCorner, 0); }
public void Start() { Noise = new SimplexNoise(); Noise.Initialize(); Root = new QuadTreeNode(this, null, Vector2.zero, Helper.ViewDistance, 4, 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)); }
/** * 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) { ; }
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; }
// 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(); }
/** * 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; }
/** * 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) { ;}
/// <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; } } }
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); } } }
/// <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); }
/** * 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; }
/// <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); } } } }
/// <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); }
/** * 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 (); }
/** * 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()); }
/// <summary> ///Clears the quadtree of all entries. /// </summary> public void clear() { ClearHelper(root); root = factory.GetQuadTreeNode(); }
public QuadTree(Rectangle argR) { firstNode = new QuadTreeNode(argR, levels); allObjects = new List <T>(); }
/// <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); }
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); }
/// <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; } }
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); }
/// <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) { /** * 遍历四个子象限的点,添加到象限点列表 * 释放子象限的内存 */ }
/** * 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) { ;}