Add function intersection for line segments

This commit is contained in:
2020-03-09 20:15:56 +01:00
parent 5fc13e0e07
commit 048f6a08e6

View File

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