Basic CGA operations
Now I wanted to separate the shapes by ZONETYPE. This would allow me to work on
the different zone types individually. First I carried out a case
(conditional) statement. To do this I needed to close the Lot rule and pass the transformed
shape onto a single successor (Lot1). The successor could then be used to carry out the
conditional rule:
## Rules
@startRule
Lot -->
alignScopeToGeometry(yUp, auto)
set(ParcelArea, geometry.area)
report("A Parcel
Area (m2)", ParcelArea)
Lot1
Lot1 -->
case ZONETYPE == "Residential" : ResidentialLot
else
: CommercialLot
Note that a case statement
must include an else, and that there are a number of special characters that
must be used. Now I had a successor that contained the residential
shapes (ResidentialLot) and another that contained the commercial shapes
(CommercialLot)
@Range(0,5)
attr YARD
= 2.5
Using the ResidentialLot successor I applied the code below - the setback operation. Note
that the operation has certain information that it requires - the setback
distance, setback selector operator and the remainder operator.
ResidentialLot -->
setback(YARD) {street.front : NIL | remainder : ResidentialLot2}
After updating the models you can now see that the residential shapes now
have the yard area removed. The slider YARD slider can be played with to
increase/decrease the setback distance.
In this example, I knew that all of the parcel shapes were regular in their geometry (all nice rectangles) and so only a few simple operations needed to be applied to achieve my simple goals. By removing the yard area it guarantees that the residential buildings would not be built within the yard. This is a pretty basic planning rule that is often applied to all types of zoning. Now I could concentrate on the building shape before making the building the coverage I wanted.
On the ResidentialLot2
successor I carried out an innerRect function (to give a completely regular rectangle) and then an shapeL function that will give the building a more of a house feel. This is a very basic residential structure and could be made far more complex by adding further operations. Instead of just one operation before a successor is generated, you can see that here I have stacked the innerRect and ShapeL operations together before having to create a successor.
ResidentialLot2 -->
innerRect
shapeL(scope.sz*0.75,scope.sx*0.75)
{shape : ResidentialLot3 | remainder : NIL}
Simple calculations and elementary looping
I now had a simple house style shape. The next type of planning rule that I wished to apply was a building coverage. I created an attribute and slider called COVERAGE (under the Attributes heading) that had a default
value of 30 (%) and a range of 25 to 100 (%). This is the coverage as a percentage of
the original parcel area (ParcelArea).
@Range(25,100)
attr COVERAGE = 30
On the next successor (ResidentialLot3) I added a Set
and Report operation that calculate the size of the geometry area that we need to meet the to reach the coverage
required (FootprintNeeded). This requires setting a value that takes the ParcelArea
and calculates the FootprintNeeded as a percentage. In order for the FootprintNeeded value to be set I also needed to create a Hidden Attribute (just like for ParcelArea)
ResidentialLot3 -->
set(FootprintNeeded, (ParcelArea/100)*COVERAGE)
report("B
Footprint Needed (m2)", FootprintNeeded)
ResidentialLot4
A simple loop was created where the successor is continually passed back to the parent, gradually decreasing the shape size
until the area is the same or less than the value for FootprintNeeded. A size
operation within a case statement asks if the geometry.area is more than the FootprintNeeded, if so
the shape is reduced in size, and is centred. It is then passed
back up to the parent successor where
the same case statement works again until the area is as required and past to a
new successor.
ResidentialLot4 -->
case geometry.area > FootprintNeeded : s('0.99,0,'0.99) center(xz) ResidentialLot4
else
: ResidentialLot5
Note the characters used in the size function. The apostrophe evokes the
relative use of the operator, essentially in this case I reduced the size
of the shape to 99% of its original size each time it passes through the loop.
The models now looked like the image below, reflecting the coverage that is
required.
The 2D element to the residential buildings were now pretty much complete. I could of course play with the sliders to dynamically change either or both the Yard and Coverage values but the image above shows all shapes with the default.
In the next post I'll run through how to create some simple code that deals with a very gentle terrain and also some basic model detail to take our 2D shapes and create 3D models.
No comments:
Post a Comment