add windows, multiple windows, alternate window patern and vertical crossbars

This commit is contained in:
AKreuzer
2024-05-19 18:11:32 +02:00
parent e6d66cc18e
commit fb6206c52f
5 changed files with 94 additions and 32 deletions

View File

@@ -42,11 +42,12 @@ class Facade:
rd.randint(self.rdata["windows"]["size"]["min_height"],max_height) rd.randint(self.rdata["windows"]["size"]["min_height"],max_height)
) )
def get_window(self) -> Window:
return Window(self.rdata["windows"] ,self.window_size)
def has_balcony(self) -> bool: def has_balcony(self) -> bool:
pass pass
def has_inter_floor(self) -> bool: def has_inter_floor(self) -> bool:
pass pass
def get_window(self) -> Window:
return Window(self.rdata["windows"] ,self.window_size)

View File

@@ -2,6 +2,7 @@ import random as rd
import math import math
from gdpc import Editor, Block, geometry from gdpc import Editor, Block, geometry
from utils.Enums import DIRECTION from utils.Enums import DIRECTION
from buildings.geometry.Point import Point
from buildings.geometry.Vertice import Vertice from buildings.geometry.Vertice import Vertice
class Window: class Window:
@@ -10,44 +11,91 @@ class Window:
self.width, self.height = size self.width, self.height = size
self.is_grounded = self.is_grounded() self.is_grounded = self.is_grounded()
self.has_multiple_windows = self.has_multiple_windows() self.has_multiple_windows = self.has_multiple_windows()
self.is_alternate = self.is_alternate()
self.has_vertical_crossbar, self.has_horizontal_crossbar = self.has_crossbars()
self.padding = 0 self.padding = 0
self.editor, self.materials = None,None
def build(self, editor : Editor, vertice : Vertice, height : int, y : int, materials : list[str]): def build(self, editor : Editor, vertice : Vertice, height : int, y : int, materials : list[str]):
self.padding = (vertice.get_size() - self.width)//2 self.editor = editor
self.materials = materials
len = vertice.get_size()
self.padding = (len - self.width)//2
self.width = len - self.padding*2
self.is_alternate = True
if not self.is_grounded: y += (height - self.height)//2 if not self.is_grounded: y += (height - self.height)//2
if self.has_multiple_windows: self.build_multiple_windows(editor, vertice, self.padding, self.height, y, materials) if self.has_multiple_windows: self.build_multiple_windows(vertice, y)
else : vertice.fill(editor, materials[1], y, y + self.height, xpadding = self.padding, zpadding = self.padding) else :
xpadding, zpadding = self.padding, self.padding
if vertice.facing == DIRECTION.NORTH or vertice.facing == DIRECTION.SOUTH: zpadding = 0
else: xpadding = 0
self.place_glasses(Point(vertice.point1.x+xpadding, y, vertice.point1.z+zpadding),
Point(vertice.point2.x-xpadding, y+self.height, vertice.point2.z-zpadding))
def build_multiple_windows(self, editor : Editor, vertice : Vertice, padding : int, height : int, y : int, materials : list[str]): def build_multiple_windows(self, vertice : Vertice, y : int):
slices = rd.randint(2, self.width//self.rdata["size"]["min_width"]) slices = rd.randint(3, self.width//self.rdata["size"]["min_width"])
windows_count = math.ceil(slices/2) mid = math.ceil(slices/2)
windows_count = mid
inter_count = slices - windows_count inter_count = slices - windows_count
window_size = rd.randint(self.rdata["size"]["min_width"], self.width-inter_count // windows_count) window_size = rd.randint(self.rdata["size"]["min_width"], (self.width-inter_count) // windows_count)
inter_size = (self.width - window_size*windows_count) // inter_count inter_size = (self.width - window_size*windows_count) // inter_count
revert, switching = slices % 2 == 0, math.ceil(slices/2) is_even= slices % 2 == 0
is_revert, gap = False, 0 is_window, gap = True, 0
remainder = self.width - (window_size*windows_count + inter_size*inter_count)
for i in range(1,slices+1): for i in range(1,slices+1):
modulo = i % 2 wsize,isize = window_size, inter_size
if revert and i == switching: is_revert = True if is_even and i == mid: wsize, isize = wsize*2, isize*2
if i == mid: wsize, isize = wsize + remainder, isize + remainder
# kepp a spacing between windows, "is revert" is used to keep symetry # kepp a spacing between windows, "is revert" is used to keep symetry
if modulo == 0 or (modulo == 1 and is_revert): if is_window:
#set the values to orient windows in x or z axis #set the values to orient windows in x or z axis
xpadding,xlen,zpadding,zlen = 0,0,0,0 xpadding,xlen,zpadding,zlen = 0,0,0,0
if vertice.facing == DIRECTION.NORTH or vertice.facing == DIRECTION.SOUTH: if vertice.facing == DIRECTION.NORTH or vertice.facing == DIRECTION.SOUTH:
xpadding,xlen = self.padding + gap, window_size xpadding,xlen = self.padding + gap, wsize-1
else: zpadding,zlen = self.padding + gap, window_size else: zpadding,zlen = self.padding + gap, wsize-1
geometry.placeCuboid(editor, self.place_glasses(Point(vertice.point1.x+xpadding, y, vertice.point1.z+zpadding),
(vertice.point1.x+xpadding, y, vertice.point1.z+zpadding), Point(vertice.point1.x+xpadding+xlen, y+self.height, vertice.point1.z+zpadding+zlen))
(vertice.point1.x+xpadding+xlen, y+self.height, vertice.point1.z+zpadding+zlen), gap += wsize
Block(materials[1]))
gap += window_size
else : else :
gap += inter_size gap += isize
is_window = not is_window
def place_glasses(self, pos1 : Point, pos2 : Point):
xlen, zlen = pos2.x - pos1.x, pos2.z - pos1.z
len = xlen + zlen
if self.is_alternate:
mid = len//2 + 1
is_block, is_even = False, len % 2 == 1 # yeah the result isn't actually even but it's because either xlen or zlen is 1, we want to know of the other result is even
for x in range(xlen+1):
for z in range(zlen+1):
if is_even and (x+z) == mid: is_block = not is_block # to keep symetry
id = 1 if not is_block else 2
geometry.placeCuboid(self.editor,(pos1.x+x,pos1.y,pos1.z+z),(pos1.x+x,pos2.y,pos1.z+z),Block(self.materials[id]))
is_block = not is_block
else:
geometry.placeCuboid(self.editor,pos1.position,pos2.position,Block(self.materials[1]))
self.build_crossbars(pos1, pos2, len)
def build_crossbars(self, pos1 : Point, pos2 : Point, len : int):
if self.has_vertical_crossbar and self.height >= self.rdata["crossbars"]["min_height_for_vertical_crossbar"]:
print(pos1.x,pos2.x)
y = self.height//2
geometry.placeCuboid(self.editor,(pos1.x,pos1.y+y,pos1.z),(pos2.x,pos2.y-y,pos2.z),Block(self.materials[3]))
if self.has_horizontal_crossbar and len >= self.rdata["crossbars"]["min_width_for_horizontal_crossbar"]:
pass
def is_grounded(self): def is_grounded(self):
# if the window is grounded or if there is a padding between the window and the ground # if the window is grounded or if there is a padding between the window and the ground
if self.rdata["grounded"] >= rd.random(): return True if self.rdata["grounded"] >= rd.random(): return True
@@ -56,11 +104,17 @@ class Window:
def has_multiple_windows(self): def has_multiple_windows(self):
if self.width > self.rdata["size"]["max_width"]: return True if self.width > self.rdata["size"]["max_width"]: return True
if self.width >= self.rdata["multiple"]["min_width"]: if self.width >= self.rdata["multiple"]["min_width"]:
return True
if self.rdata["multiple"]["proba"] >= rd.random(): return True if self.rdata["multiple"]["proba"] >= rd.random(): return True
return False return False
def open(self): def is_alternate(self):
pass # if the window alternate between glass_blocks and glass_panes
if self.rdata["alternate"] >= rd.random(): return True
return False
def close(self): def has_crossbars(self):
pass # if the window has crossbars
data = self.rdata["crossbars"]
return (data["vertical_crossbar"] >= rd.random(), data["horizontal_crossbar"] >= rd.random())

View File

@@ -17,5 +17,5 @@ class Vertice(Rectangle):
Point(x = self.point2.x, z = self.point2.z + 1)] Point(x = self.point2.x, z = self.point2.z + 1)]
def get_size(self): def get_size(self):
return self.point2.x - self.point1.x + self.point2.z - self.point1.z return self.point2.x - self.point1.x + self.point2.z - self.point1.z + 1

View File

@@ -1,4 +1,4 @@
from gdpc import Editor, Block, geometry from gdpc import Editor, Block, geometry, Transform
import networks.curve as curve import networks.curve as curve
import numpy as np import numpy as np
from utils.JsonReader import JsonReader from utils.JsonReader import JsonReader
@@ -18,8 +18,12 @@ shapes = f.data
y = YamlReader('params.yml') y = YamlReader('params.yml')
random_data = y.data random_data = y.data
transform = Transform((-2,0,-5),rotation = 3)
editor.transform.push(transform)
geometry.placeCuboid(editor, (0,-60,-5), (100,-45,-5), Block("air")) geometry.placeCuboid(editor, (0,-60,-5), (100,-45,-5), Block("air"))
x = 0 x = 0
facade = [] facade = []
for i in range(3,13): for i in range(3,13):
@@ -27,7 +31,8 @@ for i in range(3,13):
x += i+2 x += i+2
for f in facade: for f in facade:
f.build(editor, ["stone_bricks", "glass_pane"], -60) f.build(editor, ["stone_bricks","glass_pane","glass","cobblestone_wall"], -60)
# F = Foundations((0,0), (20,20), shapes[0]['matrice']) # F = Foundations((0,0), (20,20), shapes[0]['matrice'])
# F.polygon.fill_polygon(editor, "stone", -60) # F.polygon.fill_polygon(editor, "stone", -60)

View File

@@ -28,7 +28,9 @@ buildings:
min_width_for_horizontal_crossbar: 3 min_width_for_horizontal_crossbar: 3
horizontal_crossbar: 0.25 horizontal_crossbar: 0.25
grounded: 0.5 grounded: 0.5
multiple: # alternate between block and pane
alternate: 0.5
multiple:
# min size and probability of multiple windows on the same vertice # min size and probability of multiple windows on the same vertice
min_width: 5 min_width: 5
proba: 0.5 proba: 0.5