Fix naming convention

This commit is contained in:
2024-05-27 20:43:49 +02:00
parent 9bece74ffd
commit db3a8b24c1
7 changed files with 83 additions and 147 deletions

18
main.py
View File

@@ -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"))

View File

@@ -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