From 048f6a08e6d952b60601972b459ef0dc7fccefc5 Mon Sep 17 00:00:00 2001 From: Pascal Lais Date: Mon, 9 Mar 2020 20:15:56 +0100 Subject: [PATCH] Add function intersection for line segments --- linesegment.py | 72 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 69 insertions(+), 3 deletions(-) diff --git a/linesegment.py b/linesegment.py index 4c1c8b2..2e2fdc5 100644 --- a/linesegment.py +++ b/linesegment.py @@ -9,8 +9,12 @@ class LineSegment: starting at a startpoint and ending at a endpoint.""" def __init__(self, startpoint=point.Point(), endpoint=point.Point()): """Initialize the line segment.""" - self.set_startpoint(startpoint) - self.set_endpoint(endpoint) + if startpoint.get_x() <= endpoint.get_x(): + self.set_startpoint(startpoint) + self.set_endpoint(endpoint) + else: + self.set_startpoint(endpoint) + self.set_endpoint(startpoint) def set_startpoint(self, new_startpoint): """Set or change the startpoint of the line segment. If not a Point object is given the startpoint gets set to a default value of Point(0,0).""" @@ -30,6 +34,32 @@ class LineSegment: diff_x = abs(self.__startpoint.get_x() - self.__endpoint.get_x()) diff_y = abs(self.__startpoint.get_y() - self.__endpoint.get_y()) return ((diff_x ** 2) + (diff_y ** 2)) ** (1/2.0) + def get_slope(self): + """Calculate and return the slope of the line segment""" + if self.__startpoint.get_x() == self.__endpoint.get_x(): + return None + diff_x = self.__endpoint.get_x() - self.__startpoint.get_x() + diff_y = self.__endpoint.get_y() - self.__startpoint.get_y() + return diff_y / diff_x + def get_y_at(self, x_val): + """Returns the y value of the line at a specific x coordinate""" + slope = self.get_slope() + start_x = self.__startpoint.get_x() + start_y = self.__startpoint.get_y() + y_intercept = start_y - (slope * start_x) + return (slope * x_val) + y_intercept + def get_min_x(self): + """Get the lowest x coordinate of the line segment""" + return min(self.__startpoint.get_x(), self.__endpoint.get_x()) + def get_max_x(self): + """Get the highest x coordinate of the line segment""" + return max(self.__startpoint.get_x(), self.__endpoint.get_x()) + def get_min_y(self): + """Get the lowest y coordinate of the line segment""" + return min(self.__startpoint.get_y(), self.__endpoint.get_y()) + def get_max_y(self): + """Get the highest y coordinate of the line segment""" + return max(self.__startpoint.get_y(), self.__endpoint.get_y()) def str(self): """Return the line segment values as string.""" return self.__startpoint.str() + "-->" + self.__endpoint.str() @@ -38,5 +68,41 @@ class LineSegment: def get_random(min_x=0, max_x=100, min_y=0, max_y=100): """Set the point to a random place inside the boundaries""" - return LineSegment(point.Point(random.randint(min_x, max_x), random.randint(min_y, max_y)), \ + seg = LineSegment(point.Point(random.randint(min_x, max_x), random.randint(min_y, max_y)), \ point.Point(random.randint(min_x, max_x), random.randint(min_y, max_y))) + while ls.get_startpoint().get_x() == ls.get_endpoint().get_x(): + seg = LineSegment(point.Point(random.randint(min_x, max_x), random.randint(min_y, max_y)), \ + point.Point(random.randint(min_x, max_x), random.randint(min_y, max_y))) + return seg + +def intersection(ls_a, ls_b): + """Calculate the intersection between two line segments. Returns None if there isn't a + intersection, the Point of the intersection if there is one or the overlapping linesegment""" + res = None + # Check if intervalls are overlapping + if ls_a.get_max_x() < ls_b.get_min_x() or \ + ls_a.get_min_x() > ls_b.get_max_x() or \ + ls_a.get_max_y() < ls_b.get_min_y() or \ + ls_a.get_min_y() > ls_b.get_max_y(): + res = None + elif ls_a.get_slope() == ls_b.get_slope(): + if ls_a.get_y_at(0) == ls_b.get_y_at(0): + startpoint = None + endpoint = None + if ls_a.get_startpoint().get_x() > ls_b.get_startpoint().get_x(): + startpoint = ls_a.get_startpoint() + else: + startpoint = ls_b.get_startpoint() + if ls_a.get_endpoint().get_x() < ls_b.get_endpoint().get_x(): + endpoint = ls_a.get_endpoint() + else: + endpoint = ls_b.get_endpoint() + + res = LineSegment(startpoint, endpoint) + else: + x_val = (ls_a.get_y_at(0) - ls_b.get_y_at(0)) / \ + (ls_b.get_slope() - ls_a.get_slope()) + if ls_a.get_min_x() <= x_val <= ls_a.get_max_x(): + y_val = (ls_a.get_slope() * x_val) + ls_a.get_y_at(0) + res = point.Point(x_val, y_val) + return res