From ac86f8588ea40e7c448ab9aaca2a69de2ef9f002 Mon Sep 17 00:00:00 2001 From: Xeon0X Date: Tue, 11 Jun 2024 17:04:40 +0200 Subject: [PATCH] Add nearest support to Point3D --- main.py | 8 -------- networks/geometry/Point2D.py | 18 +++++++++++++++--- networks/geometry/Point3D.py | 20 +++++++++++++++++++- networks/geometry/point_tools.py | 4 ---- 4 files changed, 34 insertions(+), 16 deletions(-) diff --git a/main.py b/main.py index 0b38b73..cb71a71 100644 --- a/main.py +++ b/main.py @@ -264,11 +264,3 @@ block_list = ["blue_concrete", "red_concrete", "green_concrete", # # polyline._alpha_assign(1, polyline.length_polyline-1) # print(polyline.alpha_radii) - - -s = Segment2D(Point2D(0, 0), Point2D(10, 15), 1) -print(s) - - -c = Circle(Point2D(0, 0), 5, 10) -print(c.circle_points(10, 10)) diff --git a/networks/geometry/Point2D.py b/networks/geometry/Point2D.py index 0498f61..a251545 100644 --- a/networks/geometry/Point2D.py +++ b/networks/geometry/Point2D.py @@ -1,5 +1,6 @@ import numpy as np -import math +from typing import List +from math import atan2, sqrt class Point2D: @@ -47,9 +48,20 @@ class Point2D: else: return (s_p <= 0) and (t_p <= 0) and (s_p + t_p) >= d - def distance(self, point: "Point2D"): + def distance(self, point: "Point2D") -> int: return sqrt((point.x - self.x) ** 2 + (point.y - self.y) ** 2) + def nearest(self, points: List["Point2D"]) -> "Point2D": + """Return the nearest point. If multiple nearest point, returns the first in the list. + + Args: + points (List[Point2D]): List of the points to test. + + Returns: + Point2D: The nearest point, and if multiple, the first in the list. + """ + return min(points, key=lambda point: self.distance(point)) + def angle(self, xy1, xy2): """ Compute angle (in degrees). Corner in current point. @@ -73,7 +85,7 @@ class Point2D: v0 = np.array(xy1.coordinate) - np.array(self.coordinate) v1 = np.array(xy2.coordinate) - np.array(self.coordinate) - angle = math.atan2(np.linalg.det([v0, v1]), np.dot(v0, v1)) + angle = atan2(np.linalg.det([v0, v1]), np.dot(v0, v1)) return np.degrees(angle) def round(self, ndigits: int = None) -> "Point2D": diff --git a/networks/geometry/Point3D.py b/networks/geometry/Point3D.py index d280575..ddfc80b 100644 --- a/networks/geometry/Point3D.py +++ b/networks/geometry/Point3D.py @@ -1,3 +1,7 @@ +from typing import List +from math import atan2, sqrt + + class Point3D: def __init__(self, x: int, y: int, z: int): self.x = x @@ -11,11 +15,25 @@ class Point3D: return (self.x, self.y, self.z) def __repr__(self): - return f"Point2D(x: {self.x}, y: {self.y}, z: {self.z})" + return f"Point3D(x: {self.x}, y: {self.y}, z: {self.z})" def distance(self, point: "Point3D"): return sqrt((point.x - self.x) ** 2 + (point.y - self.y) ** 2 + (point.z - self.z) ** 2) + def nearest(self, points: List["Point3D"]) -> "Point3D": + """Return the nearest point. If multiple nearest point, returns the first in the list. + + Args: + points (List[Point2D]): List of the points to test. + + Returns: + Point3D: The nearest point, and if multiple, the first in the list. + + >>> print(Point3D(0, 0, 0).nearest((Point3D(-10, 10, 5), Point3D(10, 10, 1)))) + Point3D(x: 10, y: 10, z: 1) + """ + return min(points, key=lambda point: self.distance(point)) + def round(self, ndigits: int = None) -> "Point3D": self.x = round(self.x, ndigits) self.y = round(self.y, ndigits) diff --git a/networks/geometry/point_tools.py b/networks/geometry/point_tools.py index 14fc45f..bd9bca0 100644 --- a/networks/geometry/point_tools.py +++ b/networks/geometry/point_tools.py @@ -17,10 +17,6 @@ def optimized_path(points, start=None): return path -def nearest(points, start): - return min(points, key=lambda x: distance(start, x)) - - def sort_by_clockwise(points): """ Sort point in a rotation order. Works in 2d but supports 3d.