From dfc277ddf24f337c3093be874a39cf5ce88cb855 Mon Sep 17 00:00:00 2001 From: Xeon0X Date: Tue, 11 Jun 2024 19:34:28 +0200 Subject: [PATCH] Add perpendicular --- main.py | 3 +++ networks/geometry/Point2D.py | 2 +- networks/geometry/Segment2D.py | 33 +++++++++++++++++++++------ networks/geometry/Segment3D.py | 1 + networks/geometry/point_tools.py | 38 -------------------------------- 5 files changed, 31 insertions(+), 46 deletions(-) diff --git a/main.py b/main.py index b08ddef..029ec59 100644 --- a/main.py +++ b/main.py @@ -267,3 +267,6 @@ block_list = ["blue_concrete", "red_concrete", "green_concrete", # print(polyline.alpha_radii) print(Polyline((Point2D(0, 0), Point2D(0, 10), Point2D(50, 10), Point2D(20, 20)))) + +s = Segment3D(Point3D(0, 0, 0), Point3D(10, 10, 10)).perpendicular(10) +print(s) diff --git a/networks/geometry/Point2D.py b/networks/geometry/Point2D.py index 472332a..f5db5ff 100644 --- a/networks/geometry/Point2D.py +++ b/networks/geometry/Point2D.py @@ -183,7 +183,7 @@ class Point2D: return self @staticmethod - def to_vectors(points: List["Point3D"]): + def to_vectors(points: List["Point3D"]) -> List[np.array]: vectors = [] for point in points: vectors.append(np.array(point.coordinate)) diff --git a/networks/geometry/Segment2D.py b/networks/geometry/Segment2D.py index 59d3015..3801777 100644 --- a/networks/geometry/Segment2D.py +++ b/networks/geometry/Segment2D.py @@ -1,19 +1,17 @@ -from typing import Type +from typing import List from networks.geometry.Enums import LINE_OVERLAP, LINE_THICKNESS_MODE from networks.geometry.Point2D import Point2D +from math import sqrt class Segment2D: - def __init__(self, start: Point2D, end: Point2D, thickness: int, thickness_mode: LINE_THICKNESS_MODE = LINE_THICKNESS_MODE.MIDDLE): + def __init__(self, start: Point2D, end: Point2D, thickness_mode: LINE_THICKNESS_MODE = LINE_THICKNESS_MODE.MIDDLE): self.start = start self.end = end self.coordinates = [] - self.thickness = thickness + self.thickness = None self.thickness_mode = thickness_mode - self.compute_thick_segment( - self.start, self.end, self.thickness, self.thickness_mode) - def __repr__(self): return str(self.coordinates) @@ -27,7 +25,7 @@ class Segment2D: end (Point2D): End point of the segment. overlap (LINE_OVERLAP): Overlap draws additional pixel when changing minor direction. For standard bresenham overlap, choose LINE_OVERLAP_NONE. Can also be LINE_OVERLAP_MAJOR or LINE_OVERLAP_MINOR. - >>> Segment2D(Point2D(0, 0), Point2D(10, 15), 1) + >>> Segment2D(Point2D(0, 0), Point2D(10, 15)) """ start = start.copy() end = end.copy() @@ -95,6 +93,8 @@ class Segment2D: end (Point2D): End point of the segment. thickness (int): Total width of the surface. Placement relative to the original segment depends on thickness_mode. thickness_mode (LINE_THICKNESS_MODE): Can be one of LINE_THICKNESS_MIDDLE, LINE_THICKNESS_DRAW_CLOCKWISE, LINE_THICKNESS_DRAW_COUNTERCLOCKWISE. + + >>> self.compute_thick_segment(self.start, self.end, self.thickness, self.thickness_mode) """ delta_y = end.x - start.x delta_x = end.y - start.y @@ -191,3 +191,22 @@ class Segment2D: error += delta_2x self.compute_segmen_overlap(start, end, overlap) + + def perpendicular(self, distance: int) -> List[Point2D]: + """Compute perpendicular points from both side of the segment placed at start level. + + Args: + distance (int): Distance bewteen the start point and the perpendicular. + + Returns: + List[Point2D]: Two points. First one positioned on the counterclockwise side of the segment, oriented from start to end (meaning left). + """ + delta = self.start.distance(self.end) + dx = (self.start.x - self.end.x) / delta + dy = (self.start.y - self.end.y) / delta + + x3 = self.start.x + (distance / 2) * dy + y3 = self.start.y - (distance / 2) * dx + x4 = self.start.x - (distance / 2) * dy + y4 = self.start.y + (distance / 2) * dx + return Point2D(x3, y3).round(), Point2D(x4, y4).round() diff --git a/networks/geometry/Segment3D.py b/networks/geometry/Segment3D.py index b90ad4d..c72b49f 100644 --- a/networks/geometry/Segment3D.py +++ b/networks/geometry/Segment3D.py @@ -1,3 +1,4 @@ +from typing import List from networks.geometry.Enums import LINE_OVERLAP from networks.geometry.Point3D import Point3D diff --git a/networks/geometry/point_tools.py b/networks/geometry/point_tools.py index d5c889d..1ca56bb 100644 --- a/networks/geometry/point_tools.py +++ b/networks/geometry/point_tools.py @@ -138,33 +138,6 @@ def circle_segment_intersection( return intersections -def perpendicular(distance, xy1, xy2): - """ - Return a tuple of the perpendicular coordinates. - - Args: - distance (int): Distance from the line[xy1;xy2]. - xy1 (tuple): First coordinates. - xy2 (tuple): Second coordinates. - - Returns: - tuple: Coordinates of the line length distance, perpendicular - to [xy1; xy2] at xy1. - """ - (x1, y1) = xy1[0], xy1[-1] - (x2, y2) = xy2[0], xy2[-1] - dx = x1 - x2 - dy = y1 - y2 - dist = sqrt(dx * dx + dy * dy) - dx /= dist - dy /= dist - x3 = x1 + (distance / 2) * dy - y3 = y1 - (distance / 2) * dx - x4 = x1 - (distance / 2) * dy - y4 = y1 + (distance / 2) * dx - return (x3, y3), (x4, y4) - - def curved_corner_by_distance( intersection, xyz0, xyz1, distance_from_intersection, resolution, full_line=True ): @@ -345,14 +318,3 @@ def curved_corner_by_curvature( distance_from_intersection = round(distance(start_curve_point, center)) return curve_corner_points, center, distance_from_intersection, parallel( (xyz0, intersection), -curvature_radius), parallel((xyz1, intersection), curvature_radius) - - -def coordinates_to_vectors(coordinates): - vectors = [] - for coordinate in coordinates: - vectors.append(np.array(coordinate.coordinate)) - - if (len(vectors) == 1): - return vectors[0] - else: - return vectors