This page contains documentation of work done by Henning Biermann, Aaron Hertzmann, and Jon Meyer for a class run by Professor Chi Yap. Subsequently, this work was integrated into a joint paper, published at:
Yap, C., Biermann, B., Hertzmann, A., Li, C., Meyer, J., Pao, H.S., Paxia, S., Statistical generation of city models, Proceedings of SPIE Visualization and Data Analysis 2002. To appear.
Also see A Different Manhattan Project
We have developed a program which generates VRML models that have the same "texture" as Manhattan, although not the full detail. The models are generated using statistical methods, within a framework containing some fixed information.
We have also created a parser for "Block Details" files that can use the same VRML generator to output cities generated by other groups. (see below).
In this document we first outline our City generator, and then describe the Block Details parser generator.
See:
VRML City - a 3D VRML model generated by our City generator.
(we slightly edited this model to add one or two extra details not generated by the City generator).
We give a short overview on how we generate Manhattan-like examples:
First we define a shape representing the course structure of the Manhattan island. This shape structure is a String array that looks like:
" xx ",
" xxx ",
" xxxx",
" xxxx",
" xxx",
" xxxx",
" xxxx",
" xxxx",
" xxxxx",
" xxxxx",
" xxxxx",
" xxxxxxx",
" xxxxxxxxx",
" xxxxxxxxx", // 110th street
" xxxx xxxxx", // 110
" xxxx xxxxx", // 100
" xxxx xxxxx", // 90
" xxxx xxxxx", // 80th street
" xxxx xxxx", // 70
" xxxx xxxx", // 60
" xxxx xxxx", // 50
" xxxxxxxxxx", // 40
" xxxxxxxxxx", // 30
" xxxxxxxxxx", // 20
" xxxx E xxx", // 10th
" xxxxxxxxx",
" xxxxxxxxx",
" xxxxxxxxx",
" xxxxxxxxx",
" xxxxxxxxx",
" xxxxxxxxx",
" xxxxxxx",
" xxxxxx",
" x T x",
" xx",
For all places in the shape string containing an "x", the system generates up to three random height buildings. For the "T" entry and the "E" entry the system generates VRML for the Twin Towers and Empire State building landmarks repspectively.
We define a height field for the buildings according to a Gaussian distribution centered at 5Ave and 50th Street (h(x) = c1 * exp(|c2*(x-x0)|^2)), with another peak in the downtown district. Low buildings are randomly scattered within the higher buildings to accentuate the higher buildings. We add a random value to this height to make the profile more realistic. The constants were determined experimentally. The full code for determining the height of a building is:
double x = (ave * 400 + bldg*92);
double y = (st * 100);
double width = 200;
double length = 80;
double v = Math.random(); // pick a random number
// Use a bell curve for midtown
double height = v*v*300 +
900*Math.exp(-(0.001*(st-100)*(st-100) + 0.1*(ave-7)*(ave-7)));
// Bell curve for downtown
height +=
1500*Math.exp(-(0.05*(st-20)*(st-20) + 0.1*(ave-10)*(ave-10)));
// Introduce some jitter
if (Math.random() > .8)
height = 40;
To add texture to the City, we randomly pick between one of three VRML materials. The materials are shades of gray, but contain specks to look like small lights.
A view of downtown, with some slight post-processing to add more detail (the spire and the triangle). Our model contains approximately 10000 polygons. A model of this size allows real-time fly-throughs on the SGIs of the Media Lab.
A side view. Notice the height profile in midtown and downtown.
Another view of downtown.
A top view - here you can see the gap representing central park, and also the coarse outline of Manhattan used by this model.
The real thing!
In addition to the simple VRML city generator described above, we have also implemented a parser for use by other groups who have generated "Block Detail" files. This parser takes Block Detail files and uses the same VRML generator as described above to convert the file to VRML. For now, we only handle building records from the "Block Detail" files.
The parser/generator consists of three phases. The first phase parses the input into a generic data structure. The second phase extracts building records (their HEIGHT and POLYGON fields). Finally, the building records are output as VRML code. Buildings are modeled as VRML IndexedFaceSets, to allow finer control over texture placement (or something like that).
Given the input record:
[FILETYPE] "Block Details"
[RECORD_TYPE] BLOCK_RECORD
[BLOCK_ID] 1
[RECORD_TYPE] BUILDING
[HEIGHT] 35
[POLYGON] 4
100.0 100.0
100.0 130.0
130.0 130.0
[POLYGON_END]
[TEX_IDS] 0 1 2
[DEFAULT_COLOR] BROWN
[RECORD_END]
[LANDMARK_ID] 3
14
3
5
[LANDMARK_END]
[RECORD_END]
[ENDFILE]
Our program looks only at the building records. Basically, we treat the input above like the following code:
[FILETYPE] "Block Details"
[RECORD_TYPE] BLOCK_RECORD
[BLOCK_ID] 1
[RECORD_TYPE] BUILDING
[HEIGHT] 35.0
[POLYGON] 3
100 100
100 130
130 130
[POLYGON_END]
[RECORD_END] // BUILDING
[RECORD_END]
[ENDFILE]
This code can be converted to VRML, as seen below (note that we have omitted the nodes for material property for simplicity (see here for the complete VRML code).
#VRML V2.0 utf8 CosmoWorlds V1.0
Group {
children [
Shape {
geometry IndexedFaceSet {
coord Coordinate {
point [
100 100 0,
100 130 0,
130 130 0,
100 100 35,
100 130 35,
130 130 35
]
} # Coordinate
coordIndex [
0, 1, 4, 3, -1,
1, 2, 5, 4, -1,
2, 0, 3, 5, -1,
3, 4, 5, , -1
]
} # Geometry
} # Shape
]
} #Group