Skip to content

Instantly share code, notes, and snippets.

@bhelyer
Created February 20, 2010 20:50
Show Gist options
  • Save bhelyer/309901 to your computer and use it in GitHub Desktop.
Save bhelyer/309901 to your computer and use it in GitHub Desktop.
module dls.model.citytree;
import dls.util.rect;
enum Quad
{
NE,
NW,
SW,
SE
}
/**
* When a Node gets below these dimensions,
* it becomes a Block carrying node, containing
* the actual block information.
*/
immutable int kMinBlockWidth = 100;
immutable int kMinBlockLength = 100;
/**
* Subdivide a given area based on a quadrant.
* Params:
* quad = The quadrant to subdivide to.
* width = The maximum width of the area.
* length = The maximum length of the area.
* area = The Rect!(int) to fill out with the subdivision information.
*/
void subdivide(in Quad quad, in int width, in int length, out Rect!(int) area)
in
{
assert(width > 0);
assert(length > 0);
}
body
{
switch (quad) {
case Quad.NE:
area.x = 0;
area.y = 0;
area.x2 = width / 2;
area.y2 = length / 2;
break;
case Quad.NW:
area.x = width / 2;
area.y = 0;
area.x2 = width;
area.y2 = length / 2;
break;
case Quad.SW:
area.x = 0;
area.y = length / 2;
area.x2 = width / 2;
area.y2 = length;
break;
case Quad.SE:
area.x = width / 2;
area.y = length / 2;
area.x2 = width;
area.y2 = length;
break;
default:
assert(false);
}
}
/**
* The QuadTree representation of the city.
*
* Everything should be as lazy as possible;
* no section should be generated until asked for.
*/
class CityTree
{
/**
* Construct a new CityTree instance.
* Params:
* width = The width of the city, in metres.
* length = The length of the city, in metres.
*/
this(int width, int length)
{
mWidth = width;
mLength = length;
}
ZoneNode child(Quad quad)
{
if (mChildren[quad] is null) {
Rect!(int) area;
subdivide(quad, mWidth, mLength, area);
mChildren[quad] = new ZoneNode(area);
}
return mChildren[quad];
}
private ZoneNode[4] mChildren;
private int mWidth;
private int mLength;
}
class ZoneNode
{
this(Rect!(int) area)
{
mArea = area;
if (area.width <= kMinBlockWidth && area.length <= kMinBlockLength) {
blockNode = true;
}
}
protected Rect!(int) mArea;
protected ZoneNode[] mZoneChildren;
protected BlockNode[] mBlockChildren;
invariant()
{
assert(!(mZoneChildren !is null && mBlockChildren !is null));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment