All checks were successful
continuous-integration/drone/push Build is passing
124 lines
5.5 KiB
Python
124 lines
5.5 KiB
Python
#!/usr/bin/python3
|
|
"""The linesegment module defines the class LineSegment."""
|
|
|
|
import random
|
|
import point
|
|
|
|
class LineSegment:
|
|
"""The class LineSegment defines a two-dimensional line segment in the coordinate system
|
|
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)
|
|
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)."""
|
|
self.__startpoint = new_startpoint
|
|
def get_startpoint(self):
|
|
"""Returns the current startpoint"""
|
|
return self.__startpoint
|
|
def set_endpoint(self, new_endpoint):
|
|
"""Set or change the endpoint of the line segment. If not a Point object is given
|
|
the endpoint gets set to a default value of Point(0,0)."""
|
|
self.__endpoint = new_endpoint
|
|
def get_endpoint(self):
|
|
"""Returns the current endpoint"""
|
|
return self.__endpoint
|
|
def get_length(self):
|
|
"""Returns the length of the line segment."""
|
|
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 __getitem__(self, index):
|
|
"""Get an Endpoint by index"""
|
|
if index == 0:
|
|
return self.__startpoint
|
|
elif index == 1:
|
|
return self.__endpoint
|
|
else:
|
|
return None
|
|
def __setitem__(self, index, value):
|
|
"""Set an Endpoint by index"""
|
|
if index == 0:
|
|
self.set_startpoint(value)
|
|
elif index == 1:
|
|
self.set_endpoint(value)
|
|
def __str__(self):
|
|
"""Return the line segment values as string."""
|
|
return str(self.__startpoint) + "-->" + str(self.__endpoint)
|
|
def draw(self, canvas, width, height, max_x, max_y, color="#000000"):
|
|
"""Draw the line segment in a canvas."""
|
|
from_x, from_y = self.__startpoint.draw(canvas, width, height, max_x, max_y, color)
|
|
to_x, to_y = self.__endpoint.draw(canvas, width, height, max_x, max_y, color)
|
|
|
|
canvas.create_line(from_x, from_y, to_x, to_y, fill=color)
|
|
|
|
|
|
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"""
|
|
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 seg.get_startpoint().get_x() == seg.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
|