From 45c7560352e2db321c0d7dfee27319983b65473f Mon Sep 17 00:00:00 2001 From: Xeon0X Date: Thu, 6 Jun 2024 13:06:17 +0200 Subject: [PATCH] Redo roads --- main.py | 48 +++++++---- networks/geometry/point_tools.py | 134 +++++++++++++++++++++++-------- networks/roads/Road.py | 56 ++++++++++++- 3 files changed, 188 insertions(+), 50 deletions(-) diff --git a/main.py b/main.py index afbe8f3..0769421 100644 --- a/main.py +++ b/main.py @@ -212,23 +212,39 @@ block_list = ["blue_concrete", "red_concrete", "green_concrete", # --- -intersection = (-1510, 94, 455) -xyz0 = (-1545, 90, 537) -xyz1 = (-1443, 160, 452) -circle = curved_corner_by_distance( - intersection, xyz0, xyz1, 50, 0) +# intersection = (-1510, 94, 455) +# xyz0 = (-1545, 90, 537) +# xyz1 = (-1535, 162, 459) +# circle = curved_corner_by_distance( +# intersection, xyz0, xyz1, 25, 0) -line0 = segment_tools.discrete_segment(intersection, xyz0) -line1 = segment_tools.discrete_segment(intersection, xyz1) +# line0 = segment_tools.discrete_segment(intersection, xyz0) +# line1 = segment_tools.discrete_segment(intersection, xyz1, pixel_perfect=False) -for coordinate in circle[0]: - editor.placeBlock( - coordinate, Block("cyan_concrete")) +# editor.placeBlock( +# circle[1], Block("black_concrete")) -for coordinate in line0: - editor.placeBlock( - coordinate, Block("blue_concrete")) +# editor.placeBlock( +# circle[3], Block("gray_concrete")) +# print(circle[3], "center") +# print(circle[4], "center") -for coordinate in line1: - editor.placeBlock( - coordinate, Block("red_concrete")) +# for coordinate in circle[0]: +# editor.placeBlock( +# coordinate, Block("white_concrete")) +# print(coordinate) + +# for coordinate in line0: +# editor.placeBlock( +# coordinate, Block("blue_concrete")) + +# for coordinate in line1: +# editor.placeBlock( +# coordinate, Block("red_concrete")) + +# --- + +r = Road.Road(((-1572, 64, 518), (-1608, 65, 513), + (-1627, 64, 534), (-1643, 71, 580)), "None") + +r.place_roads() diff --git a/networks/geometry/point_tools.py b/networks/geometry/point_tools.py index 1e3a77e..1bfce76 100644 --- a/networks/geometry/point_tools.py +++ b/networks/geometry/point_tools.py @@ -335,65 +335,135 @@ def curved_corner_by_distance( intersection, xyz0, xyz1, distance_from_intersection, resolution, full_line=True ): # Compute the merging point on the first line - start_curve_point = circle_segment_intersection( + start_curve_point_d1 = circle_segment_intersection( intersection, distance_from_intersection, xyz0, intersection, full_line )[0] - start_curve_point = ( - round(start_curve_point[0]), nearest(discrete_segment(intersection, xyz0), (start_curve_point[0], 100, start_curve_point[-1]))[1], round(start_curve_point[-1])) + start_curve_point_d1 = ( + round(start_curve_point_d1[0]), nearest(discrete_segment(intersection, xyz0), (start_curve_point_d1[0], 100, start_curve_point_d1[-1]))[1], round(start_curve_point_d1[-1])) # Compute the merging point on the second line - end_curve_point = circle_segment_intersection( + end_curve_point_d1 = circle_segment_intersection( intersection, distance_from_intersection, xyz1, intersection, full_line )[0] - end_curve_point = ( - round(end_curve_point[0]), nearest(discrete_segment(intersection, xyz1), (end_curve_point[0], 100, end_curve_point[-1]))[1], round(end_curve_point[-1])) + end_curve_point_d1 = ( + round(end_curve_point_d1[0]), nearest(discrete_segment(intersection, xyz1), (end_curve_point_d1[0], 100, end_curve_point_d1[-1]))[1], round(end_curve_point_d1[-1])) + + # Compute the merging point on the first line + start_curve_point_d2 = circle_segment_intersection( + (intersection[0], intersection[1]), distance_from_intersection, ( + xyz0[0], xyz0[1]), (intersection[0], intersection[1]), full_line + )[0] + start_curve_point_d2 = ( + round(start_curve_point_d2[0]), round(start_curve_point_d2[1]), nearest(discrete_segment(intersection, xyz0), (start_curve_point_d1[0], start_curve_point_d2[-1], 100))[-1]) + + # Compute the merging point on the second line + end_curve_point_d2 = circle_segment_intersection( + (intersection[0], intersection[1] + ), distance_from_intersection, (xyz1[0], xyz1[1]), (intersection[0], intersection[1]), full_line + )[0] + end_curve_point_d2 = ( + round(end_curve_point_d2[0]), round(end_curve_point_d2[-1]), nearest(discrete_segment( + intersection, xyz1), (end_curve_point_d2[0], end_curve_point_d2[-1], 100))[-1]) # Compute the intersection between perpendicular lines at the merging points # Higher value for better precision - perpendicular0 = perpendicular(10e3, start_curve_point, intersection)[0] - perpendicular0 = (round(perpendicular0[0]), round(perpendicular0[-1])) - perpendicular1 = perpendicular(10e3, end_curve_point, intersection)[1] - perpendicular1 = (round(perpendicular1[0]), round(perpendicular1[-1])) + perpendicular0_d1 = perpendicular( + 10e3, start_curve_point_d1, intersection)[0] + perpendicular0_d1 = ( + round(perpendicular0_d1[0]), round(perpendicular0_d1[-1])) + perpendicular1_d1 = perpendicular( + 10e3, end_curve_point_d1, intersection)[1] + perpendicular1_d1 = ( + round(perpendicular1_d1[0]), round(perpendicular1_d1[-1])) - center = segments_intersection( - (perpendicular0, start_curve_point), (perpendicular1, end_curve_point)) - center = round(center[0]), middle_point(xyz0, xyz1)[1], round(center[-1]) + perpendicular0_d2 = perpendicular( + 10e3, (start_curve_point_d1[0], start_curve_point_d1[1]), (intersection[0], intersection[1]))[0] + perpendicular0_d2 = ( + round(perpendicular0_d2[0]), round(perpendicular0_d2[1])) + perpendicular1_d2 = perpendicular( + 10e3, (end_curve_point_d1[0], end_curve_point_d1[1]), (intersection[0], intersection[1]))[1] + perpendicular1_d2 = ( + round(perpendicular1_d2[0]), round(perpendicular1_d2[1])) + + # Centers + center_d1 = segments_intersection( + (perpendicular0_d1, start_curve_point_d1), (perpendicular1_d1, end_curve_point_d1)) + center_d1 = round(center_d1[0]), middle_point( + xyz0, xyz1)[1], round(center_d1[-1]) + + center_d2 = segments_intersection( + (perpendicular0_d2, (start_curve_point_d1[0], start_curve_point_d1[1])), (perpendicular1_d2, (end_curve_point_d1[0], end_curve_point_d1[1]))) + center_d2 = round(center_d2[0]), round(center_d2[1]), middle_point( + xyz0, xyz1)[-1] # Compute the curvature for indications - curvature = round(distance(start_curve_point, center)) + curvature_d1 = round(distance(start_curve_point_d1, center_d1)) + curvature_d2 = round( + distance((start_curve_point_d1[0], start_curve_point_d1[1]), center_d2)) # Return a full discrete circle or only some points of it if resolution != 0: - circle_data = circle_points( - center, curvature, resolution + circle_data_d1 = circle_points( + center_d1, curvature_d1, resolution + ) + circle_data_d2 = circle_points( + center_d2, curvature_d2, resolution ) else: - print(center, curvature, circle(center, curvature)) - circle_data = circle(center, curvature)[0] + circle_data_d1 = circle(center_d1, curvature_d1)[0] + circle_data_d2 = circle(center_d2, curvature_d2)[0] # Find the correct points on the circle. - curved_corner_points_temporary = [start_curve_point] - for point in circle_data: - if is_in_triangle(point, intersection, start_curve_point, end_curve_point): - curved_corner_points_temporary.append(point) - curved_corner_points_temporary.append(end_curve_point) + curved_corner_points_temporary_d1 = [start_curve_point_d1] + for point in circle_data_d1: + if is_in_triangle(point, intersection, start_curve_point_d1, end_curve_point_d1): + curved_corner_points_temporary_d1.append(point) + curved_corner_points_temporary_d1.append(end_curve_point_d1) # Be sure that all the points are in correct order. - curve_corner_points = optimized_path( - curved_corner_points_temporary, start_curve_point) + curve_corner_points_d1 = optimized_path( + curved_corner_points_temporary_d1, start_curve_point_d1) - for i in range(len(curve_corner_points)): - y = min(start_curve_point[1], end_curve_point[1]) + \ - (i * abs(start_curve_point[1] - - end_curve_point[1])/len(curve_corner_points)) - curve_corner_points[i] = (round(curve_corner_points[i][0]), round( - y), round(curve_corner_points[i][-1])) - return curve_corner_points, center, curvature + # On the other axis + curved_corner_points_temporary_d2 = [ + (start_curve_point_d1[0], start_curve_point_d1[1])] + for point in circle_data_d2: + + if is_in_triangle(point, (intersection[0], intersection[1]), (start_curve_point_d1[0], start_curve_point_d1[1]), (end_curve_point_d1[0], end_curve_point_d1[1])): + curved_corner_points_temporary_d2.append(point) + curved_corner_points_temporary_d2.append( + (end_curve_point_d1[0], end_curve_point_d1[1])) + + # Be sure that all the points are in correct order. + curve_corner_points_d2 = optimized_path( + curved_corner_points_temporary_d2, (start_curve_point_d1[0], start_curve_point_d1[1])) + + # Determine driving axis + if len(curve_corner_points_d1) <= len(curve_corner_points_d2): + main_points = curve_corner_points_d2 + projected_points = curve_corner_points_d1 + else: + main_points = curve_corner_points_d1 + projected_points = curve_corner_points_d2 + + print("Main\n") + print(main_points) + print("Projected\n") + print(projected_points) + + curve_corner_points = [] + for i in range(len(main_points)): + y = projected_points[round( + i * (len(projected_points)-1)/len(main_points))][-1] + curve_corner_points.append((round(main_points[i][0]), round( + y), round(main_points[i][-1]))) + return curve_corner_points, center_d1, curvature_d1, center_d2, curvature_d2 def curved_corner_by_curvature( intersection, xyz0, xyz1, curvature_radius, resolution, full_line=True ): + # 3d support limited to linear interpollation on the y axis. print(xyz0, intersection, xyz1) # Get the center. center = segments_intersection(parallel( diff --git a/networks/roads/Road.py b/networks/roads/Road.py index 4eeb66b..1522f6c 100644 --- a/networks/roads/Road.py +++ b/networks/roads/Road.py @@ -1,8 +1,60 @@ +import networks.geometry.curve_tools as curve_tools +import networks.geometry.Strip as Strip + +from gdpc import Editor, Block, geometry + + class Road: def __init__(self, coordinates, road_configuration): - self.coordinates = coordinates # List of tuples (x1, y1, z1) in order + self.coordinates = coordinates self.road_configuration = road_configuration # 'road', 'highway' self.width = 10 # TODO def place_roads(self): - pass + editor = Editor(buffering=True) + + self.resolution, self.distance = curve_tools.resolution_distance( + self.coordinates, 6) + + self.curve_points = curve_tools.curve( + self.coordinates, self.resolution) + self.curve_surface = Strip.Strip(self.coordinates) + self.curve_surface.compute_curvature() + + self.curvature = [] + for i in range(len(self.curve_surface.curvature)): + self.curvature.append((0, 1, 0)) + + # Perpendicular + self.curve_surface.compute_surface_perpendicular(10, self.curvature) + for i in range(len(self.curve_surface.surface)): + for j in range(len(self.curve_surface.surface[i])): + # block = random.choice(block_list) + for k in range(len(self.curve_surface.surface[i][j])): + editor.placeBlock( + self.curve_surface.surface[i][j][k], Block("blackstone")) + +# offset = curve.offset(curve_surface.curve, -9, curvature) +# for i in range(len(offset)-1): +# line = segment.discrete_segment(offset[i], offset[i+1]) +# for coordinate in line: +# editor.placeBlock(coordinate, Block("white_concrete")) + +# offset = curve.offset(curve_surface.curve, 9, curvature) +# for i in range(len(offset)-1): +# line = segment.discrete_segment(offset[i], offset[i+1]) +# for coordinate in line: +# editor.placeBlock(coordinate, Block("white_concrete")) + +# # for coordinate in curve_surface.surface: +# # editor.placeBlock(coordinate, Block("black_concrete")) + +# # for coordinate in curve_surface.curve: +# # editor.placeBlock(coordinate, Block("red_concrete")) + +# # # Parallel +# # curve_surface.compute_surface_parallel(0, 10, 8, curvature) + +# # for current_range in range(len(curve_surface.left_side)): +# # for coordinate in curve_surface.left_side[current_range]: +# # editor.placeBlock(coordinate, Block("yellow_concrete"))