download QuadTree.cs
Language: C#
Copyright: (c) 2006 by Tank Monkey Games
LOC: 141
Project Info
HappySprite
Server: Spider_20090120_inc
Type: filesystem
...zip\HappySprite\Collisions\
   AlignedBox.cs
   BoxBase.cs
   Circle.cs
   CollisionDetails.cs
   CollisionManager.cs
   CollisionOptions.cs
   CollisionShape.cs
   OrientedBox.cs
   QuadTree.cs

//=============================================================================
//     _   _                               ____                _  _          
//    | | | |  __ _  _ __   _ __   _   _  / ___|  _ __   _ __ (_)| |_   ___ 
//    | |_| | / _` || '_ \ | '_ \ | | | | \___ \ | '_ \ | '__|| || __| / _ \
//    |  _  || (_| || |_) || |_) || |_| |  ___) || |_) || |   | || |_ |  __/
//    |_| |_| \__,_|| .__/ | .__/  \__, | |____/ | .__/ |_|   |_| \__| \___|
//                  |_|    |_|     |___/         |_|                         
//
//                     HappySprite - We make sprites happy
//
// Copyright (c) 2006 by Tank Monkey Games
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//=============================================================================

using System;
using System.Drawing;
using System.Collections.Generic;

namespace HappySprite.Collisions
{
	public class QuadTree<T>
	{
		#region Private Properties
		int _depth;
		RectangleF _rect;
		List<T> _objects = null;

		private QuadTree<T> _topLeftChild = null;
        private QuadTree<T> _topRightChild = null;
        private QuadTree<T> _bottomLeftChild = null;
        private QuadTree<T> _bottomRightChild = null;
		#endregion
	
		#region Public Properties
		public RectangleF Rect
		{
			get { return _rect; }
		}

		public QuadTree<T> TopLeftChild
		{
			get { return _topLeftChild; }
		}

        public QuadTree<T> TopRightChild
		{
			get { return _topRightChild; }
		}

        public QuadTree<T> BottomLeftChild
		{
			get { return _bottomLeftChild; }
		}

        public QuadTree<T> BottomRightChild
		{
			get { return _bottomRightChild; }
		}
		#endregion

		private void Add(T obj)
		{
			if (_objects == null)
				_objects = new List<T>();

			_objects.Add(obj);
		}

		private void Remove(T obj)
		{
			if (_objects.Contains(obj))
				_objects.Remove(obj);
		}


		public QuadTree(RectangleF rect, int depth)
		{
			_rect = rect;
			_depth = depth;
		}

		public void Insert(RectangleF rect, T obj)
		{
			// if no intersection quit
			if (RectangleF.Intersect(_rect, rect).IsEmpty)
				return;

			if (_depth == 0)
			{
				Add(obj);
				return;
			}
		
			// if we have no children create some
			if (_topLeftChild == null)
			{
				float childWidth = _rect.Width / 2;
				float childHeight = _rect.Height / 2;

				_topLeftChild = new QuadTree<T>(new RectangleF(_rect.X, _rect.Y, childWidth, childHeight), _depth -1);
                _topRightChild = new QuadTree<T>(new RectangleF(_rect.X + childWidth, _rect.Y, childWidth, childHeight), _depth - 1);
                _bottomLeftChild = new QuadTree<T>(new RectangleF(_rect.X, _rect.Y + childHeight, childWidth, childHeight), _depth - 1);
                _bottomRightChild = new QuadTree<T>(new RectangleF(_rect.X + childWidth, _rect.Y + childHeight, childWidth, childHeight), _depth - 1);
			}

			// insert the object in our children
			_topLeftChild.Insert(rect, obj);
			_topRightChild.Insert(rect, obj);
			_bottomLeftChild.Insert(rect, obj);
			_bottomRightChild.Insert(rect, obj);
		}

		public void Remove(RectangleF rect, T obj)
		{
			if (_depth == 0)
			{
				Remove(obj);
			}
			else if (_topLeftChild != null)
			{
				_topLeftChild.Remove(rect, obj);
				_topRightChild.Remove(rect, obj);
				_bottomLeftChild.Remove(rect, obj);
				_bottomLeftChild.Remove(rect, obj);
			}
		}

		public void Clear()
		{
			if (_depth == 0 && _objects != null)
			{
				_objects.Clear();
			}
			else if (_topLeftChild != null)
			{
				_topLeftChild.Clear();
				_topRightChild.Clear();
				_bottomLeftChild.Clear();
				_bottomRightChild.Clear();
			}
		}

		public List<T> Get(RectangleF rect)
		{
			// if it doesn't intersect us then it's not going to intersect our children either
			if (RectangleF.Intersect(_rect, rect).IsEmpty)
				return null;

			// are there children to test?
			if (_topLeftChild == null)
			{
				if (_objects == null || _objects.Count == 0)
					return null;
				else
					return _objects;
			}

			List<T> topLeftChildObjects = _topLeftChild.Get(rect);
            List<T> topRightChildObjects = _topRightChild.Get(rect);
            List<T> bottomLeftChildObjects = _bottomLeftChild.Get(rect);
            List<T> bottomRightChildObjects = _bottomRightChild.Get(rect);

            List<T> results = new List<T>();

			if(topLeftChildObjects != null)
				foreach(T o in topLeftChildObjects)
					if( ! results.Contains(o) )
						results.Add(o);

			if(topRightChildObjects != null)
				foreach(T o in topRightChildObjects)
					if( ! results.Contains(o) )
						results.Add(o);

			if(bottomLeftChildObjects != null)
				foreach(T o in bottomLeftChildObjects)
					if( ! results.Contains(o) )
						results.Add(o);

			if(bottomRightChildObjects != null)
				foreach(T o in bottomRightChildObjects)
					if( ! results.Contains(o) )
						results.Add(o);

			return results;
		}
	}
}

About Koders | Resources | Downloads | Support | Black Duck | Submit Project | Terms of Service | DMCA | Privacy Policy | Site Map| Contact Us