Created
February 20, 2010 20:50
-
-
Save bhelyer/309901 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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