From db3a8b24c1bbac02f5ffe90a0990e0bf78edc8c9 Mon Sep 17 00:00:00 2001 From: Xeon0X Date: Mon, 27 May 2024 20:43:49 +0200 Subject: [PATCH] Fix naming convention --- main.py | 18 +- networks/geometry/point.py | 212 ++++++------------ .../{ => roads}/intersections/Intersection.py | 0 networks/{ => roads}/lanes/Lane.py | 0 networks/{ => roads}/lanes/lanes.json | 0 networks/{ => roads}/lines/Line.py | 0 networks/{ => roads}/lines/lines.json | 0 7 files changed, 83 insertions(+), 147 deletions(-) rename networks/{ => roads}/intersections/Intersection.py (100%) rename networks/{ => roads}/lanes/Lane.py (100%) rename networks/{ => roads}/lanes/lanes.json (100%) rename networks/{ => roads}/lines/Line.py (100%) rename networks/{ => roads}/lines/lines.json (100%) diff --git a/main.py b/main.py index 947e690..27a74d0 100644 --- a/main.py +++ b/main.py @@ -1,5 +1,5 @@ -import networks.lines.Line as Line -import networks.lanes.Lane as Lane +import networks.roads.lines.Line as Line +import networks.roads.lanes.Lane as Lane from gdpc import Editor, Block, geometry import networks.geometry.curve as curve import networks.geometry.CurveSurface as CurveSurface @@ -9,7 +9,7 @@ import json from buildings.Building import Building import random -from networks.geometry.point import curveCornerIntersectionLine, curveCornerIntersectionPoints +from networks.geometry.point import curved_corner_intersection editor = Editor(buffering=True) @@ -107,11 +107,11 @@ block_list = ["blue_concrete", "red_concrete", "green_concrete", # print(l.get_surface()) -circle = curveCornerIntersectionLine( - ((-1313, 392), (-1378, 415)), ((-1371, 348), (-1341, 439)), 30, angleAdaptation=True) +circle = curved_corner_intersection( + ((-1313, 392), (-1378, 415)), ((-1371, 348), (-1341, 439)), 30, angle_adaptation=True, output_only_points=False) -print(circle[0]) +print(circle) -for coordinate in circle[0]: - editor.placeBlock( - (round(coordinate[0]), 100, round(coordinate[1])), Block("green_concrete")) +# for coordinate in circle[0]: +# editor.placeBlock( +# (round(coordinate[0]), 100, round(coordinate[1])), Block("green_concrete")) diff --git a/networks/geometry/point.py b/networks/geometry/point.py index e659af4..a195205 100644 --- a/networks/geometry/point.py +++ b/networks/geometry/point.py @@ -2,7 +2,7 @@ from math import sqrt, cos, pi, sin import numpy as np -def circle(xyC, r): +def circle(center, radius): """ Can be used for circle or disc. @@ -16,21 +16,22 @@ def circle(xyC, r): for a disc, positive values for a hole. """ area = ( - (round(xyC[0]) - round(r), round(xyC[1]) - round(r)), - (round(xyC[0]) + round(r) + 1, round(xyC[1]) + round(r) + 1), + (round(center[0]) - round(radius), round(center[1]) - round(radius)), + (round(center[0]) + round(radius) + 1, + round(center[1]) + round(radius) + 1), ) circle = {} for x in range(area[0][0], area[1][0]): for y in range(area[0][1], area[1][1]): - d = round(distance2D((x, y), (xyC))) - r + d = round(distance((x, y), (center))) - radius if circle.get(d) == None: circle[d] = [] circle[d].append((x, y)) return circle -def InTriangle(point, xy0, xy1, xy2): +def is_in_triangle(point, xy0, xy1, xy2): # https://stackoverflow.com/questions/2049582/how-to-determine-if-a-point-is-in-a-2d-triangle#:~:text=A%20simple%20way%20is%20to,point%20is%20inside%20the%20triangle. dX = point[0] - xy0[0] dY = point[1] - xy0[1] @@ -49,11 +50,11 @@ def InTriangle(point, xy0, xy1, xy2): return (s_p <= 0) and (t_p <= 0) and (s_p + t_p) >= D -def distance2D(A, B): # TODO : Can be better. - return sqrt((B[0] - A[0]) ** 2 + (B[1] - A[1]) ** 2) +def distance(xy1, xy2): # TODO : Can be better. + return sqrt((xy2[0] - xy1[0]) ** 2 + (xy2[1] - xy1[1]) ** 2) -def getAngle(xy0, xy1, xy2): +def get_angle(xy0, xy1, xy2): """ Compute angle (in degrees) for xy0, xy1, xy2 corner. @@ -77,7 +78,7 @@ def getAngle(xy0, xy1, xy2): return np.degrees(angle) -def circlePoints(center_point, radius, number=100): +def circle_points(center_point, radius, number=100): # https://stackoverflow.com/questions/8487893/generate-all-the-points-on-the-circumference-of-a-circle points = [ (cos(2 * pi / number * x) * radius, sin(2 * pi / number * x) * radius) @@ -93,7 +94,7 @@ def circlePoints(center_point, radius, number=100): return points -def optimizedPath(points, start=None): +def optimized_path(points, start=None): # https://stackoverflow.com/questions/45829155/sort-points-in-order-to-have-a-continuous-curve-using-python if start is None: start = points[0] @@ -101,17 +102,17 @@ def optimizedPath(points, start=None): path = [start] pass_by.remove(start) while pass_by: - nearest = min(pass_by, key=lambda x: distance2D(path[-1], x)) + nearest = min(pass_by, key=lambda x: distance(path[-1], x)) path.append(nearest) pass_by.remove(nearest) return path def nearest(points, start): - return min(points, key=lambda x: distance2D(start, x)) + return min(points, key=lambda x: distance(start, x)) -def sortRotation(points): +def sort_by_clockwise(points): """ Sort point in a rotation order. Works in 2d but supports 3d. @@ -124,7 +125,7 @@ def sortRotation(points): Returns: list: List of tuples of coordinates sorted (2d or 3d). - >>> sortRotation([(0, 45, 100), (4, -5, 5),(-5, 36, -2)]) + >>> sort_by_clockwise([(0, 45, 100), (4, -5, 5),(-5, 36, -2)]) [(0, 45, 100), (-5, 36, -2), (4, -5, 5)] """ x, y = [], [] @@ -150,21 +151,21 @@ def sortRotation(points): y_sorted = list(y[mask]) # Rearrange tuples to get the right coordinates. - sortedPoints = [] + sorted_points = [] for i in range(len(points)): j = 0 while (x_sorted[i] != points[j][0]) and (y_sorted[i] != points[j][-1]): j += 1 else: if len(points[0]) == 3: - sortedPoints.append((x_sorted[i], points[j][1], y_sorted[i])) + sorted_points.append((x_sorted[i], points[j][1], y_sorted[i])) else: - sortedPoints.append((x_sorted[i], y_sorted[i])) + sorted_points.append((x_sorted[i], y_sorted[i])) - return sortedPoints + return sorted_points -def lineIntersection(line0, line1, fullLine=True): +def segments_intersection(line0, line1, full_line=True): """ Find (or not) intersection between two lines. Works in 2d but supports 3d. @@ -174,13 +175,13 @@ def lineIntersection(line0, line1, fullLine=True): Args: line0 (tuple): Tuple of tuple of coordinates. line1 (tuple): Tuple of tuple of coordinates. - fullLine (bool, optional): True to find intersections along + full_line (bool, optional): True to find intersections along full line - not just in the segment. Returns: tuple: Coordinates (2d). - >>> lineIntersection(((0, 0), (0, 5)), ((2.5, 2.5), (-2.5, 2.5))) + >>> segments_intersection(((0, 0), (0, 5)), ((2.5, 2.5), (-2.5, 2.5))) """ xdiff = (line0[0][0] - line0[1][0], line1[0][0] - line1[1][0]) ydiff = (line0[0][-1] - line0[1][-1], line1[0][-1] - line1[1][-1]) @@ -196,7 +197,7 @@ def lineIntersection(line0, line1, fullLine=True): x = det(d, xdiff) / div y = det(d, ydiff) / div - if not fullLine: + if not full_line: if ( min(line0[0][0], line0[1][0]) <= x <= max(line0[0][0], line0[1][0]) and min(line1[0][0], line1[1][0]) @@ -216,8 +217,8 @@ def lineIntersection(line0, line1, fullLine=True): return x, y -def circleLineSegmentIntersection( - circleCenter, circleRadius, xy0, xy1, fullLine=True, tangentTol=1e-9 +def circle_segment_intersection( + circle_center, circle_radius, xy0, xy1, full_line=True, tangent_tolerance=1e-9 ): """ Find the points at which a circle intersects a line-segment. This @@ -227,16 +228,16 @@ def circleLineSegmentIntersection( Note: We follow: http://mathworld.wolfram.com/Circle-LineIntersection.html Args: - circleCenter (tuple): The (x, y) location of the circle center. - circleRadius (int): The radius of the circle. + circle_center (tuple): The (x, y) location of the circle center. + circle_radius (int): The radius of the circle. xy0 (tuple): The (x, y) location of the first point of the segment. xy1 ([tuple]): The (x, y) location of the second point of the segment. - fullLine (bool, optional): True to find intersections along + full_line (bool, optional): True to find intersections along full line - not just in the segment. False will just return intersections within the segment. Defaults to True. - tangentTol (float, optional): Numerical tolerance at which we + tangent_tolerance (float, optional): Numerical tolerance at which we decide the intersections are close enough to consider it a tangent. Defaults to 1e-9. @@ -248,13 +249,13 @@ def circleLineSegmentIntersection( (p1x, p1y), (p2x, p2y), (cx, cy) = ( (xy0[0], xy0[-1]), (xy1[0], xy1[-1]), - (circleCenter[0], circleCenter[1]), + (circle_center[0], circle_center[1]), ) (x1, y1), (x2, y2) = (p1x - cx, p1y - cy), (p2x - cx, p2y - cy) dx, dy = (x2 - x1), (y2 - y1) dr = (dx ** 2 + dy ** 2) ** 0.5 big_d = x1 * y2 - x2 * y1 - discriminant = circleRadius ** 2 * dr ** 2 - big_d ** 2 + discriminant = circle_radius ** 2 * dr ** 2 - big_d ** 2 if discriminant < 0: # No intersection between circle and line return [] @@ -274,7 +275,7 @@ def circleLineSegmentIntersection( for sign in ((1, -1) if dy < 0 else (-1, 1)) ] # This makes sure the order along the segment is correct if ( - not fullLine + not full_line ): # If only considering the segment, filter out intersections that do not fall within the segment fraction_along_segment = [ (xi - p1x) / dx if abs(dx) > abs(dy) else (yi - p1y) / dy @@ -286,7 +287,7 @@ def circleLineSegmentIntersection( if 0 <= frac <= 1 ] if ( - len(intersections) == 2 and abs(discriminant) <= tangentTol + len(intersections) == 2 and abs(discriminant) <= tangent_tolerance ): # If line is tangent to circle, return just one point (as both intersections have same location) return [intersections[0]] else: @@ -320,8 +321,8 @@ def perpendicular(distance, xy1, xy2): return ((round(x3), round(y3)), (round(x4), round(y4))) -def curveCornerIntersectionPoints( - line0, line1, startDistance, angleAdaptation=False +def curved_corner_intersection( + line0, line1, start_distance, angle_adaptation=False, full_line=False, center=(), output_only_points=True ): """ Create points between the two lines to smooth the intersection. @@ -329,140 +330,75 @@ def curveCornerIntersectionPoints( Args: line0 (tuple): Tuple of tuple. Line coordinates. Order matters. line1 (tuple): Tuple of tuple. Line coordinates. Order matters. - startDistance (int): distance from the intersection where the + start_distance (int): distance from the intersection where the curve should starts. angleAdaptation (bool, optional): True will adapt the - startDistance depending of the angle between the two lines. - False will force the distance to be startDistance. Defaults to + start_distance depending of the angle between the two lines. + False will force the distance to be start_distance. Defaults to False. Returns: [list]: List of tuple of coordinates (2d) that forms the curve. Starts on the line and end on the other line. - >>> curveCornerIntersectionPoints(((0, 0), (50, 20)), ((-5, 50), (25, -5)), 10) + >>> curved_corner_intersection(((0, 0), (50, 20)), ((-5, 50), (25, -5)), 10) """ - intersection = lineIntersection(line0, line1, fullLine=True) + intersection = segments_intersection(line0, line1, full_line) if intersection == None: return None # Define automatically the distance from the intersection, where the curve # starts. - if angleAdaptation: - angle = getAngle( + if angle_adaptation: + angle = get_angle( (line0[0][0], line0[0][-1]), intersection, (line1[0][0], line1[0][-1]), ) # Set here the radius of the circle for a square angle. - startDistance = startDistance * abs(1 / (angle / 90)) + start_distance = start_distance * abs(1 / (angle / 90)) - startCurvePoint = circleLineSegmentIntersection( - intersection, startDistance, line0[0], intersection, fullLine=True + start_curve_point = circle_segment_intersection( + intersection, start_distance, line0[0], intersection, full_line )[0] - endCurvePoint = circleLineSegmentIntersection( - intersection, startDistance, line1[0], intersection, fullLine=True + start_curve_point = ( + round(start_curve_point[0]), round(start_curve_point[1])) + end_curve_point = circle_segment_intersection( + intersection, start_distance, line1[0], intersection, full_line )[0] + end_curve_point = (round(end_curve_point[0]), round(end_curve_point[1])) # Higher value for better precision - perpendicular0 = perpendicular(10e3, startCurvePoint, intersection)[0] - perpendicular1 = perpendicular(10e3, endCurvePoint, intersection)[1] + perpendicular0 = perpendicular(10e3, start_curve_point, intersection)[0] + perpendicular1 = perpendicular(10e3, end_curve_point, intersection)[1] - center = lineIntersection( - (perpendicular0, startCurvePoint), (perpendicular1, endCurvePoint) - ) + if center == (): + center = segments_intersection( + (perpendicular0, start_curve_point), (perpendicular1, end_curve_point) + ) + center = round(center[0]), round(center[1]) # Distance with startCurvePoint and endCurvePoint from the center are the # same. - radius = distance2D(startCurvePoint, center) + radius = round(distance(start_curve_point, center)) - circle = circlePoints( - center, round(radius), 32 - ) # n=round((2 * pi * radius) / 32) + if output_only_points: + circle_data = circle_points( + center, radius, 32 + ) # n=round((2 * pi * radius) / 32) + else: + circle_data = circle(center, radius)[0] # Find the correct point on the circle. - curveCornerPointsTemp = [startCurvePoint] - for point in circle: - if InTriangle(point, intersection, startCurvePoint, endCurvePoint): - curveCornerPointsTemp.append(point) - curveCornerPointsTemp.append(endCurvePoint) + 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( + (round(point[0]), round(point[1]))) + if output_only_points: + curved_corner_points_temporary.append(end_curve_point) # Be sure that all the points are in correct order. - curveCornerPoints = optimizedPath(curveCornerPointsTemp, startCurvePoint) - return curveCornerPoints - - -def curveCornerIntersectionLine( - line0, line1, startDistance, angleAdaptation=False, center=() -): - """ - Create a continuous circular line between the two lines to smooth - the intersection. - - Args: - line0 (tuple): Tuple of tuple. Line coordinates. Order matters. - line1 (tuple): Tuple of tuple. Line coordinates. Order matters. - startDistance (int): distance from the intersection where the - curve should starts. - angleAdaptation (bool, optional): True will adapt the - startDistance depending of the angle between the two lines. - False will force the distance to be startDistance. Defaults to - False. - - Returns: - [list]: List of tuple of coordinates (2d) that forms the curve. - Starts on the line and end on the other line. - - TODO: - angleAdaptation : Set circle radius and not startDistance. - Polar coordinates / Unit circle instead of InTriangle. - - >>> curveCornerIntersectionLine(((0, 0), (50, 20)), ((-5, 50), (25, -5)), 10) - """ - intersection = lineIntersection(line0, line1, fullLine=True) - - if intersection == None: - return None - - # Define automatically the distance from the intersection, where the curve - # starts. - if angleAdaptation: - angle = getAngle( - (line0[0][0], line0[0][-1]), - intersection, - (line1[0][0], line1[0][-1]), - ) - # Set here the radius of the circle for a square angle. - startDistance = startDistance * abs(1 / (angle / 90)) - - startCurvePoint = circleLineSegmentIntersection( - intersection, startDistance, line0[0], intersection, fullLine=True - )[0] - endCurvePoint = circleLineSegmentIntersection( - intersection, startDistance, line1[0], intersection, fullLine=True - )[0] - # Higher value for better precision - perpendicular0 = perpendicular(10e3, startCurvePoint, intersection)[0] - perpendicular1 = perpendicular(10e3, endCurvePoint, intersection)[1] - - if center == (): - center = lineIntersection( - (perpendicular0, startCurvePoint), (perpendicular1, endCurvePoint) - ) - - # Distance with startCurvePoint and endCurvePoint from the center - # are almost the same. - radius = distance2D(startCurvePoint, center) - - circleArc = circle(center, round(radius))[0] - - # Find the correct point on the circle. - curveCornerPointsTemp = [startCurvePoint] - for point in circleArc: - if InTriangle(point, intersection, startCurvePoint, endCurvePoint): - curveCornerPointsTemp.append(point) - # curveCornerPointsTemp.append(endCurvePoint) - - # Be sure that all the points are in correct order. - curveCornerPoints = optimizedPath(curveCornerPointsTemp, startCurvePoint) - return curveCornerPoints, center + curve_corner_points = optimized_path( + curved_corner_points_temporary, start_curve_point) + return curve_corner_points, center, radius diff --git a/networks/intersections/Intersection.py b/networks/roads/intersections/Intersection.py similarity index 100% rename from networks/intersections/Intersection.py rename to networks/roads/intersections/Intersection.py diff --git a/networks/lanes/Lane.py b/networks/roads/lanes/Lane.py similarity index 100% rename from networks/lanes/Lane.py rename to networks/roads/lanes/Lane.py diff --git a/networks/lanes/lanes.json b/networks/roads/lanes/lanes.json similarity index 100% rename from networks/lanes/lanes.json rename to networks/roads/lanes/lanes.json diff --git a/networks/lines/Line.py b/networks/roads/lines/Line.py similarity index 100% rename from networks/lines/Line.py rename to networks/roads/lines/Line.py diff --git a/networks/lines/lines.json b/networks/roads/lines/lines.json similarity index 100% rename from networks/lines/lines.json rename to networks/roads/lines/lines.json