Because the orientation of street houses must account for the south-facing of all units, the orientation and the placement axis can be treated separately.
The
array axes are therefore divided broadly into the following:
- Longest segment axis of the plot geometry
- Boundary axis
- South-facing axis
The rules governing the
array axes, derived from the layout analysis, are as follows:
- One array axis has a minimum of 1 and a maximum of 3 origins.
- The array axes have a minimum of 1 and a maximum of 2 axes when the Boundary axis is not selected.
- If the selected array-axis parameter is the Boundary axis,
N line segments are offset into the site.
- A corner-type building is placed at the intersection of the lines offset from the site boundary axis.
- The range of the offset parameters is
SITE_BOUNDARY_OFFSET_DISTANCE_LIST, which follows the analysis below.
Analysis of SITE_BOUNDARY_OFFSET_DISTANCE_LIST
class Consts:
TOLERANCE_TO_SIMPLIFY = 10
TOLERANCE_ANGLE_TO_SIMPLIFY = 10
SITE_BOUNDARY_OFFSET_DISTANCE_LIST = [15, 20, 25]
SITE_BOUNDARY_NUMBER_TO_USE = 4
def get_axis(site_geom):
simplified_site_geom = gh.SimplifyCurve(
curve=site_geom,
tolerance=Consts.TOLERANCE_TO_SIMPLIFY,
angle_tolerance=Consts.TOLERANCE_ANGLE_TO_SIMPLIFY
).curve
sorted_simplified_site_geom = sorted(
exploded_simplified_site_geom,
key=lambda s: s.GetLength(),
reverse=True
)
(...)
# When Boundary axis parameter be selected,
# sort the segments of site geometry by the length of each segment
# and offset each segment as much as SITE_BOUNDARY_NUMBER_TO_USE
elif param_axis == Enums.BOUNDARIES_ARRAY_AXIS:
axis = sorted_simplified_site_geom[:Consts.SITE_BOUNDARY_NUMBER_TO_USE]
If the Boundary axis is selected, the units' directions follow the site boundary axis.
If the aspect ratio of the OBB created for the site's long axis exceeds ASPECT_RATIO_BASELINE, no other axes are searched and the long axis is fixed.
class Consts:
ASPECT_RATIO_BASELINE = 1.91
is_aspect_ratio_gte_baseline = (
get_aspect_ratio_by_longest_segment(simplified_site_geom)
>= Consts.ASPECT_RATIO_BASELINE
)
if is_aspect_ratio_gte_baseline:
Parameters.param_axis = param_axis = Enums.LONGEST_ARRAY_AXIS
| Parameter |
Type |
Range |
| param_axis |
discrete |
0, 1, 2, 3, 4 |
| param_axis_count |
discrete |
1, 2 |
| param_axis_flip |
discrete |
0, 1 |
| param_axis_positions |
continuous |
[0 ~ 1] * param_axis_count |
| param_south_facing_degree |
discrete |
0, 1, 2 ... len(SOUTH_FACING_DEGREE_LIST) |
| param_offset_distance |
discrete |
0, 1, 2 … len(SITE_BOUNDARY_OFFSET_DISTANCE_LIST) |
| param_building_positions |
continuous |
Refer the get_param_building_positions function |
| param_building_positions_count |
discrete |
Refer the get_param_building_positions function |
Parameter descriptions:
- param_axis: Parameter for selecting the axis
- param_axis_count: The count of axes
- param_axis_flip: Whether flip 90˚ when
Longest segment axis is selected
- param_axis_positions: Positions of the array axes
- param_south_facing_degree: Parameter to select south-facing degree
- param_offset_distance: Offset distance when
Boundary axis is selected
- param_building_positions: Starting point parameter of Apt
- param_building_positions_count: Starting point count parameter of Apt
State spaces by randomly distributed parameters
Parameters definition:
class Parameters:
# Enums.LONGEST_ARRAY_AXIS,
# Enums.BOUNDARIES_ARRAY_AXIS
# Enums.FULL_SOUTH_ARRAY_AXIS
param_axis = random.randint(0, 2)
# whether flip or not flip when the longest axis selected
param_axis_flip = random.randint(0, 1)
param_axis_count = random.randint(1, 2)
@staticmethod
def get_param_axis_positions(param_axis_count):
return [random.random() for _ in range(param_axis_count)]
@staticmethod
def get_param_building_positions(array_axis):
param_building_positions = []
for ax in array_axis:
param_building_positions_count = 1
ax_length = ax.GetLength()
if ax_length >= Consts.ARRAY_AXIS_LENGTH_BASELINE_HIGHEST:
param_building_positions_count = random.randint(2, 3)
elif ax_length >= Consts.ARRAY_AXIS_LENGTH_BASELINE_MIDDLE:
param_building_positions_count = random.randint(1, 2)
each_positions = [
random.random() for _ in range(param_building_positions_count)
]
param_building_positions.append(each_positions)
return param_building_positions
@staticmethod
def get_param_south_facing_degree(array_axis):
param_south_facing_degree = [
random.randrange(0, len(Consts.SOUTH_FACING_DEGREE_LIST))
for _ in array_axis
]
return param_south_facing_degree
@staticmethod
def get_param_offset_distance(axis_offset):
param_offset_distance = [
random.randrange(
0, len(Consts.SITE_BOUNDARY_OFFSET_DISTANCE_LIST)
) for _ in axis_offset
]
return param_offset_distance