diff --git a/main.py b/main.py index 3c36815..7fcb6f3 100644 --- a/main.py +++ b/main.py @@ -7,66 +7,83 @@ from world_maker.data_analysis import transpose_form_heightmap from world_maker.Skeleton import Skeleton, simplify_coordinates from world_maker.terraforming import remove_trees, smooth_terrain from networks.geometry.Point3D import Point3D +from networks.geometry.Point2D import Point2D from networks.roads_2.Road import Road from networks.legacy_roads import roads from world_maker.District import Road as Road_grid +from networks.geometry.Circle import Circle from House import * +from gdpc import Editor, Block def main(): - - rectangle_house_mountain, rectangle_building, skeleton_highway, skeleton_mountain, road_grid = world_maker() - editor = Editor(buffering=True) - buildArea = editor.getBuildArea() - origin = ((buildArea.begin).x, (buildArea.begin).z) + c = Circle(Point2D(400, -75)).circle_thick_by_line(5, 32) + for i in range(len(c[0])): + for j in range(len(c[0][i])): + if i % 2 == 0: + editor.placeBlock( + (c[0][i][j].x, 110, c[0][i][j].y), Block("white_concrete")) + else: + editor.placeBlock( + (c[0][i][j].x, 110, c[0][i][j].y), Block("black_concrete")) + print(c[1]) + for i in range(len(c[1])): + for j in range(len(c[1][i])): + editor.placeBlock( + (c[1][i][j].x, 110, c[1][i][j].y), Block("red_concrete")) + # rectangle_house_mountain, rectangle_building, skeleton_highway, skeleton_mountain, road_grid = world_maker() - remove_trees('./world_maker/data/heightmap.png', './world_maker/data/treemap.png', - './world_maker/data/smooth_sobel_watermap.png') - smooth_terrain('./world_maker/data/heightmap.png', - './world_maker/data/heightmap_smooth.png', './world_maker/data/smooth_sobel_watermap.png') + # editor = Editor(buffering=True) + # buildArea = editor.getBuildArea() + # origin = ((buildArea.begin).x, (buildArea.begin).z) - # set_roads(skeleton_mountain, origin) - # set_roads(skeleton_highway, origin) - # set_roads_grids(road_grid, origin) - # roads.setRoads(skeleton_mountain) - # roads.setRoads(skeleton_highway) + # remove_trees('./world_maker/data/heightmap.png', './world_maker/data/treemap.png', + # './world_maker/data/smooth_sobel_watermap.png') + # smooth_terrain('./world_maker/data/heightmap.png', + # './world_maker/data/heightmap_smooth.png', './world_maker/data/smooth_sobel_watermap.png') - blocks = { - "wall": "blackstone", - "roof": "blackstone", - "roof_slab": "blackstone_slab", - "door": "oak_door", - "window": "glass_pane", - "entrance": "oak_door", - "stairs": "quartz_stairs", - "stairs_slab": "quartz_slab", - "celling": "quartz_block", - "floor": "quartz_block", - "celling_slab": "quartz_slab", - "garden_outline": "oak_leaves", - "garden_floor": "grass_block" - } + # # set_roads(skeleton_mountain, origin) + # # set_roads(skeleton_highway, origin) + # # set_roads_grids(road_grid, origin) + # # roads.setRoads(skeleton_mountain) + # # roads.setRoads(skeleton_highway) - entranceDirection = ["N", "S", "E", "W"] + # blocks = { + # "wall": "blackstone", + # "roof": "blackstone", + # "roof_slab": "blackstone_slab", + # "door": "oak_door", + # "window": "glass_pane", + # "entrance": "oak_door", + # "stairs": "quartz_stairs", + # "stairs_slab": "quartz_slab", + # "celling": "quartz_block", + # "floor": "quartz_block", + # "celling_slab": "quartz_slab", + # "garden_outline": "oak_leaves", + # "garden_floor": "grass_block" + # } - for houses in rectangle_building: - start = (houses[0][0]+buildArea.begin[0], houses[0] - [1], houses[0][2]+buildArea.begin[2]) - end = (houses[1][0]+buildArea.begin[0], houses[1] - [1], houses[1][2]+buildArea.begin[2]) - house = House(editor, start, end, - entranceDirection[random.randint(0, 3)], blocks) - house.build() + # entranceDirection = ["N", "S", "E", "W"] - for houses in rectangle_house_mountain: - start = (houses[0][0]+buildArea.begin[0], houses[0] - [1], houses[0][2]+buildArea.begin[2]) - end = (houses[1][0]+buildArea.begin[0], houses[1] - [1], houses[1][2]+buildArea.begin[2]) - house = House(editor, start, end, - entranceDirection[random.randint(0, 3)], blocks) - house.build() + # for houses in rectangle_building: + # start = (houses[0][0]+buildArea.begin[0], houses[0] + # [1], houses[0][2]+buildArea.begin[2]) + # end = (houses[1][0]+buildArea.begin[0], houses[1] + # [1], houses[1][2]+buildArea.begin[2]) + # house = House(editor, start, end, + # entranceDirection[random.randint(0, 3)], blocks) + # house.build() + + # for houses in rectangle_house_mountain: + # start = (houses[0][0]+buildArea.begin[0], houses[0] + # [1], houses[0][2]+buildArea.begin[2]) + # end = (houses[1][0]+buildArea.begin[0], houses[1] + # [1], houses[1][2]+buildArea.begin[2]) + # house = House(editor, start, end, + # entranceDirection[random.randint(0, 3)], blocks) + # house.build() def set_roads_grids(road_grid: Road_grid, origin): diff --git a/networks/geometry/Circle.py b/networks/geometry/Circle.py index cda5585..3933a32 100644 --- a/networks/geometry/Circle.py +++ b/networks/geometry/Circle.py @@ -1,5 +1,5 @@ from math import cos, pi, sin -from typing import List +from typing import List, Dict import numpy as np @@ -17,6 +17,9 @@ class Circle: self.outer = None self.points_thick: List[Point2D] = [] + self.points_thick_by_line: List[List[Point2D]] = [] + self.gaps: List[Point2D] = [] + self.spaced_radius = None self.spaced_points: List[Point2D] = [] @@ -24,6 +27,7 @@ class Circle: return f"Circle(center: {self.center}, radius: {self.radius}, spaced_radius: {self.spaced_radius}, inner: {self.inner}, outer: {self.outer})" def circle(self, radius: int) -> List[Point2D]: + self.points = [] self.radius = radius center = self.center.copy() @@ -48,8 +52,59 @@ class Circle: break return self.points + def circle_thick_by_line(self, inner: int, outter: int) -> List[List[Point2D]]: + width = outter - inner + self.circle_thick_by_line = [[] for _ in range(width)] + for i in range(width): + self.circle_thick_by_line[i] = self.circle(inner + i) + if i > 0: + self.gaps.append(Circle._remove_gaps( + self.circle_thick_by_line[i], self.circle_thick_by_line[i-1])) + return self.circle_thick_by_line, self.gaps + + @staticmethod + def _remove_gaps(outter_line: List[Point2D], inner_line: List[Point2D]) -> List[Point2D]: + gaps = [] + for i in range(len(outter_line)): + if Circle._count_neighbors(outter_line[i], inner_line) == 0: + if Circle._count_neighbors(Point2D(outter_line[i].x-1, outter_line[i].y), inner_line) > 1: + if Point2D(outter_line[i].x-1, outter_line[i].y) not in outter_line: + gaps.append( + Point2D(outter_line[i].x-1, outter_line[i].y)) + if Circle._count_neighbors(Point2D(outter_line[i].x+1, outter_line[i].y), inner_line) > 1: + if Point2D(outter_line[i].x+1, outter_line[i].y) not in outter_line: + gaps.append( + Point2D(outter_line[i].x+1, outter_line[i].y)) + if Circle._count_neighbors(Point2D(outter_line[i].x, outter_line[i].y-1), inner_line) > 1: + if Point2D(outter_line[i].x, outter_line[i].y-1) not in outter_line: + gaps.append( + Point2D(outter_line[i].x, outter_line[i].y-1)) + if Circle._count_neighbors(Point2D(outter_line[i].x, outter_line[i].y+1), inner_line) > 1: + if Point2D(outter_line[i].x, outter_line[i].y+1) not in outter_line: + gaps.append( + Point2D(outter_line[i].x, outter_line[i].y+1)) + return gaps + + @ staticmethod + def _count_neighbors(point: Point2D, line: List[Point2D]) -> int: + neighbors = 0 + for i in range(len(line)): + if point.x == line[i].x: + if point.y == line[i].y: + return 0 + if point.y-1 == line[i].y: + neighbors += 1 + if point.y+1 == line[i].y: + neighbors += 1 + if point.y == line[i].y: + if point.x-1 == line[i].x: + neighbors += 1 + if point.x+1 == line[i].x: + neighbors += 1 + return neighbors + def circle_thick(self, inner: int, outer: int) -> List[Point2D]: - """Compute discrete value of a 2d-circle with thickness. + """Compute discrete value of a 2d-circle with thickness. From: https://stackoverflow.com/questions/27755514/circle-with-thickness-drawing-algorithm @@ -108,7 +163,7 @@ class Circle: From: https://stackoverflow.com/questions/8487893/generate-all-the-points-on-the-circumference-of-a-circle Args: - number (int): Number of coordinates to be returned. + number (int): Number of coordinates to be returned. radius (int): Radius of the circle. Returns: diff --git a/networks/geometry/Segment2D.py b/networks/geometry/Segment2D.py index 2acf5e8..01ba393 100644 --- a/networks/geometry/Segment2D.py +++ b/networks/geometry/Segment2D.py @@ -12,12 +12,13 @@ class Segment2D: self.end = end self.points: List[Point2D] = [] self.points_thick: List[Point2D] = [] + self.points_thick_by_line: List[Union[Point2D, int]] = [] self.thickness = None def __repr__(self): return str(f"Segment2D(start: {self.start}, end: {self.end}, points: {self.points})") - def segment(self, start: Point2D = None, end: Point2D = None, overlap: LINE_OVERLAP = LINE_OVERLAP.NONE, _is_computing_thickness: bool = False) -> Union[List[Point2D], None]: + def segment(self, start: Point2D = None, end: Point2D = None, overlap: LINE_OVERLAP = LINE_OVERLAP.NONE, _is_computing_thickness: int = 0) -> Union[List[Point2D], None]: """Modified Bresenham draw (line) with optional overlap. From: https://github.com/ArminJo/Arduino-BlueDisplay/blob/master/src/LocalGUI/ThickLine.hpp @@ -108,6 +109,8 @@ class Segment2D: >>> self.compute_thick_segment(self.start, self.end, self.thickness, self.thickness_mode) """ + self.points_thick_by_line = [[] for _ in range(thickness+1)] + start = self.start.copy() end = self.end.copy() @@ -158,7 +161,7 @@ class Segment2D: error += delta_2x self.segment( - start, end, overlap=LINE_OVERLAP.NONE, _is_computing_thickness=True) + start, end, overlap=LINE_OVERLAP.NONE, _is_computing_thickness=1) error = delta_2x - delta_x for i in range(thickness, 1, -1): @@ -173,7 +176,7 @@ class Segment2D: error += delta_2y self.segment( - start, end, overlap=overlap, _is_computing_thickness=True) + start, end, overlap=overlap, _is_computing_thickness=i) else: if swap: @@ -194,7 +197,7 @@ class Segment2D: error += delta_2x self.segment( - start, end, overlap=LINE_OVERLAP.NONE, _is_computing_thickness=True) + start, end, overlap=LINE_OVERLAP.NONE, _is_computing_thickness=1) error = delta_2x - delta_y for i in range(thickness, 1, -1): @@ -209,7 +212,7 @@ class Segment2D: error += delta_2x self.segment( - start, end, overlap=overlap, _is_computing_thickness=True) + start, end, overlap=overlap, _is_computing_thickness=i) return self.points_thick @@ -241,7 +244,9 @@ class Segment2D: ) def _add_points(self, points, is_computing_thickness): - if is_computing_thickness: + if is_computing_thickness > 0: self.points_thick.append(points.copy()) + self.points_thick_by_line[is_computing_thickness].append( + (points.copy())) else: self.points.append(points.copy()) diff --git a/networks/roads_2/Road.py b/networks/roads_2/Road.py index bffd365..a52b49f 100644 --- a/networks/roads_2/Road.py +++ b/networks/roads_2/Road.py @@ -62,8 +62,30 @@ class Road: # Get nearest in x,z projection nearest = self.polyline.segments[i].points_thick[j].nearest( Point3D.to_2d(self.polyline_total_line_output, removed_axis='y'), True) - self.output_block.append( - (Point3D.insert_3d([self.polyline.segments[i].points_thick[j]], 'y', [self.polyline_total_line_output[nearest[0]].y])[0].coordinates, Block("stone"))) + # self.output_block.append( + # (Point3D.insert_3d([self.polyline.segments[i].points_thick[j]], 'y', [self.polyline_total_line_output[nearest[0]].y])[0].coordinates, Block("stone"))) + for k in range(len(self.polyline.segments[i].points_thick_by_line)): + match k: + case 0: + blob = 'black_concrete' + case 1: + blob = 'red_concrete' + case 2: + blob = 'orange_concrete' + case 3: + blob = 'yellow_concrete' + case 4: + blob = 'green_concrete' + case 5: + blob = 'blue_concrete' + case 6: + blob = 'purple_concrete' + + for m in range(len(self.polyline.segments[i].points_thick_by_line[k])): + nearest = self.polyline.segments[i].points_thick_by_line[k][m].nearest( + Point3D.to_2d(self.polyline_total_line_output, removed_axis='y'), True) + self.output_block.append( + (Point3D.insert_3d([self.polyline.segments[i].points_thick_by_line[k][m]], 'y', [self.polyline_total_line_output[nearest[0]].y])[0].coordinates, Block(blob))) for i in range(1, len(self.polyline.centers)-1): # Circle diff --git a/world_maker/data/building.png b/world_maker/data/building.png index 0592ddc..6616794 100644 Binary files a/world_maker/data/building.png and b/world_maker/data/building.png differ diff --git a/world_maker/data/building_moutain.png b/world_maker/data/building_moutain.png index ec205e9..fd47f44 100644 Binary files a/world_maker/data/building_moutain.png and b/world_maker/data/building_moutain.png differ diff --git a/world_maker/data/city_map.png b/world_maker/data/city_map.png index 3204bd4..b8cf5d9 100644 Binary files a/world_maker/data/city_map.png and b/world_maker/data/city_map.png differ diff --git a/world_maker/data/district.png b/world_maker/data/district.png index be99e50..8ee6ca2 100644 Binary files a/world_maker/data/district.png and b/world_maker/data/district.png differ diff --git a/world_maker/data/heightmap.png b/world_maker/data/heightmap.png index fd530c9..887b02f 100644 Binary files a/world_maker/data/heightmap.png and b/world_maker/data/heightmap.png differ diff --git a/world_maker/data/heightmap_smooth.png b/world_maker/data/heightmap_smooth.png index df0ea6f..19283fe 100644 Binary files a/world_maker/data/heightmap_smooth.png and b/world_maker/data/heightmap_smooth.png differ diff --git a/world_maker/data/heightmap_with_building.png b/world_maker/data/heightmap_with_building.png index b760c78..246d2dc 100644 Binary files a/world_maker/data/heightmap_with_building.png and b/world_maker/data/heightmap_with_building.png differ diff --git a/world_maker/data/highwaymap.png b/world_maker/data/highwaymap.png index 08a915d..44c2fcb 100644 Binary files a/world_maker/data/highwaymap.png and b/world_maker/data/highwaymap.png differ diff --git a/world_maker/data/mountain_map.png b/world_maker/data/mountain_map.png index f8f9f7c..9089607 100644 Binary files a/world_maker/data/mountain_map.png and b/world_maker/data/mountain_map.png differ diff --git a/world_maker/data/removed_treesmap.png b/world_maker/data/removed_treesmap.png index 4a5ba6b..e05cb90 100644 Binary files a/world_maker/data/removed_treesmap.png and b/world_maker/data/removed_treesmap.png differ diff --git a/world_maker/data/roadmap.png b/world_maker/data/roadmap.png index ee8afc6..20938aa 100644 Binary files a/world_maker/data/roadmap.png and b/world_maker/data/roadmap.png differ diff --git a/world_maker/data/skeleton_highway.png b/world_maker/data/skeleton_highway.png index 19baad8..66aaf17 100644 Binary files a/world_maker/data/skeleton_highway.png and b/world_maker/data/skeleton_highway.png differ diff --git a/world_maker/data/skeleton_highway_area.png b/world_maker/data/skeleton_highway_area.png index aa3af81..6a84a6e 100644 Binary files a/world_maker/data/skeleton_highway_area.png and b/world_maker/data/skeleton_highway_area.png differ diff --git a/world_maker/data/skeleton_mountain.png b/world_maker/data/skeleton_mountain.png index c356aec..32f14b5 100644 Binary files a/world_maker/data/skeleton_mountain.png and b/world_maker/data/skeleton_mountain.png differ diff --git a/world_maker/data/skeleton_mountain_area.png b/world_maker/data/skeleton_mountain_area.png index 383a7a6..2db1e91 100644 Binary files a/world_maker/data/skeleton_mountain_area.png and b/world_maker/data/skeleton_mountain_area.png differ diff --git a/world_maker/data/smooth_sobel_watermap.png b/world_maker/data/smooth_sobel_watermap.png index 36096fd..e64228f 100644 Binary files a/world_maker/data/smooth_sobel_watermap.png and b/world_maker/data/smooth_sobel_watermap.png differ diff --git a/world_maker/data/smooth_terrain_delta.png b/world_maker/data/smooth_terrain_delta.png index eb480c1..44423f8 100644 Binary files a/world_maker/data/smooth_terrain_delta.png and b/world_maker/data/smooth_terrain_delta.png differ diff --git a/world_maker/data/sobelmap.png b/world_maker/data/sobelmap.png index eddca82..1afa845 100644 Binary files a/world_maker/data/sobelmap.png and b/world_maker/data/sobelmap.png differ diff --git a/world_maker/data/treemap.png b/world_maker/data/treemap.png index 7e1a02d..801a9e8 100644 Binary files a/world_maker/data/treemap.png and b/world_maker/data/treemap.png differ diff --git a/world_maker/data/watermap.png b/world_maker/data/watermap.png index 1d91fc2..acaf2c4 100644 Binary files a/world_maker/data/watermap.png and b/world_maker/data/watermap.png differ