public bool SetAABB(ref AABB2i aabb, ref T value) { var setAny = setAABBInternal(ref aabb, ref value); if (setAny) { unsubdivide(); } return(setAny); }
public bool UnsetAABB(ref AABB2i aabb) { var unsetAny = unsetAABBInternal(ref aabb); if (unsetAny) { unsubdivide(); } return(unsetAny); }
private RegionQuadtree(int resolution, int depth, T?value, RegionQuadtree <T> parent, AABB2i aabb) { this.resolution = resolution; this.depth = depth; this.value = value; this.parent = parent; this.aabb = aabb; if (value != null) { propagateEvent(EventType.Added); } }
private bool unsetAABBInternal(ref AABB2i aabb) { bool otherContains = aabb.Contains(ref this.aabb); bool otherIntersects = aabb.Intersects(ref this.aabb); if (!otherContains && otherIntersects) { if (Type == QuadType.White) { return(false); } bool subdivided = false; var canSub = depth < resolution; if (canSub && Type != QuadType.Grey) { subdivide(); subdivided = true; } bool anyChild = false; if (canSub) { foreach (var quad in quads) { anyChild |= quad.unsetAABBInternal(ref aabb); } } return(anyChild || subdivided); } else if (otherContains) { return(unsetInternal()); } else { return(false); } throw new InvalidOperationException("Set didn't fail nor succeed. This is not supposed to happen!"); }
public RegionQuadtree(int resolution) { if (resolution < 0) { throw new ArgumentException("Resolution can't be negative."); } this.resolution = resolution; this.depth = 0; var size = (int)Math.Pow(2, resolution); if (size < 0) { throw new ArgumentException("resolution is too high"); } this.aabb = new AABB2i( new Point2i(0, 0), new Point2i(size, size)); }
public bool UnsetCircle(Point2i point, int radius) { var rectSize = (int)(radius / Math.Sqrt(2)); var testAABB = new AABB2i( point - new Point2i(rectSize - 1, rectSize - 1), point + new Point2i(rectSize - 1, rectSize - 1)); bool anyOuterUnset = false; for (int i = point.X - radius; i <= point.X + radius; i++) { for (int j = point.Y - radius; j <= point.Y + radius; j++) { var currentPoint = new Point2i(i, j); if (testAABB.Contains(currentPoint)) { continue; } if ((point - currentPoint).Length() <= radius) { anyOuterUnset |= unsetInternal(ref currentPoint); } } } var anyAABBUnset = unsetAABBInternal(ref testAABB); if (anyOuterUnset || anyAABBUnset) { unsubdivide(); } return(anyOuterUnset || anyAABBUnset); }
public bool UnsetAABB(AABB2i aabb) { return(UnsetAABB(ref aabb)); }
public bool SetAABB(AABB2i aabb, T value) { return(SetAABB(ref aabb, ref value)); }
public bool SetCircle(Point2i point, int radius, T value) { var rectSize = (int)(radius / Math.Sqrt(2)); var testAABB = new AABB2i(point - new Point2i(rectSize, rectSize), point + new Point2i(rectSize, rectSize)); for (int i = point.X - radius; i <= point.X + radius; i++) { for (int j = point.Y - radius; j <= point.Y + radius; j++) { var currentPoint = new Point2i(i, j); if (testAABB.Contains(currentPoint)) { continue; } if ((point - currentPoint).Length() < radius) { if (isPointOutside(currentPoint)) { if (findRoot() == this && AutoExpand) { RegionQuadtree <T> newRoot = this; if (newRoot.isPointOutside(currentPoint)) { newRoot = newRoot.ExpandFromCenter(); point += new Point2i(newRoot.aabb.Width / 4, newRoot.aabb.Height / 4); } return(newRoot.SetCircle(point, radius, value)); } } } } } bool anyOuterSet = false; for (int i = point.X - radius; i <= point.X + radius; i++) { for (int j = point.Y - radius; j <= point.Y + radius; j++) { var currentPoint = new Point2i(i, j); if (testAABB.Contains(currentPoint)) { continue; } if ((point - currentPoint).Length() < radius) { anyOuterSet |= setInternal(ref currentPoint, ref value); } } } var anyAABBSet = setAABBInternal(ref testAABB, ref value); if (anyOuterSet || anyAABBSet) { unsubdivide(); } return(anyOuterSet || anyAABBSet); }