Add perpendicular

This commit is contained in:
2024-06-11 19:34:28 +02:00
parent f98af90b3e
commit dfc277ddf2
5 changed files with 31 additions and 46 deletions

View File

@@ -267,3 +267,6 @@ block_list = ["blue_concrete", "red_concrete", "green_concrete",
# print(polyline.alpha_radii) # print(polyline.alpha_radii)
print(Polyline((Point2D(0, 0), Point2D(0, 10), Point2D(50, 10), Point2D(20, 20)))) 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)

View File

@@ -183,7 +183,7 @@ class Point2D:
return self return self
@staticmethod @staticmethod
def to_vectors(points: List["Point3D"]): def to_vectors(points: List["Point3D"]) -> List[np.array]:
vectors = [] vectors = []
for point in points: for point in points:
vectors.append(np.array(point.coordinate)) vectors.append(np.array(point.coordinate))

View File

@@ -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.Enums import LINE_OVERLAP, LINE_THICKNESS_MODE
from networks.geometry.Point2D import Point2D from networks.geometry.Point2D import Point2D
from math import sqrt
class Segment2D: 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.start = start
self.end = end self.end = end
self.coordinates = [] self.coordinates = []
self.thickness = thickness self.thickness = None
self.thickness_mode = thickness_mode self.thickness_mode = thickness_mode
self.compute_thick_segment(
self.start, self.end, self.thickness, self.thickness_mode)
def __repr__(self): def __repr__(self):
return str(self.coordinates) return str(self.coordinates)
@@ -27,7 +25,7 @@ class Segment2D:
end (Point2D): End point of the segment. 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. 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() start = start.copy()
end = end.copy() end = end.copy()
@@ -95,6 +93,8 @@ class Segment2D:
end (Point2D): End point of the segment. 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 (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. 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_y = end.x - start.x
delta_x = end.y - start.y delta_x = end.y - start.y
@@ -191,3 +191,22 @@ class Segment2D:
error += delta_2x error += delta_2x
self.compute_segmen_overlap(start, end, overlap) 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()

View File

@@ -1,3 +1,4 @@
from typing import List
from networks.geometry.Enums import LINE_OVERLAP from networks.geometry.Enums import LINE_OVERLAP
from networks.geometry.Point3D import Point3D from networks.geometry.Point3D import Point3D

View File

@@ -138,33 +138,6 @@ def circle_segment_intersection(
return intersections 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( def curved_corner_by_distance(
intersection, xyz0, xyz1, distance_from_intersection, resolution, full_line=True 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)) distance_from_intersection = round(distance(start_curve_point, center))
return curve_corner_points, center, distance_from_intersection, parallel( return curve_corner_points, center, distance_from_intersection, parallel(
(xyz0, intersection), -curvature_radius), parallel((xyz1, intersection), curvature_radius) (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