Compare commits
No commits in common. "97e0e3c39cb0de5b4cfa3bf3b46aeff8116de6aa" and "f832238900e16223c3b32394237ec27d046772fb" have entirely different histories.
97e0e3c39c
...
f832238900
|
|
@ -18,7 +18,6 @@ ezdxf = "^1.1.4"
|
||||||
|
|
||||||
[tool.poetry.group.dev.dependencies]
|
[tool.poetry.group.dev.dependencies]
|
||||||
commitizen = "^3.13.0"
|
commitizen = "^3.13.0"
|
||||||
pytest = "^7.4.4"
|
|
||||||
|
|
||||||
[build-system]
|
[build-system]
|
||||||
requires = ["poetry-core"]
|
requires = ["poetry-core"]
|
||||||
|
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
# import sys
|
|
||||||
|
|
||||||
# sys.path.append('/home/songsenand/Project/ToyDesigner/')
|
|
||||||
|
|
||||||
from toydesigner.objects import *
|
|
||||||
|
|
||||||
|
|
||||||
def test_line():
|
|
||||||
line1 = Line((1, 3), (1, 4))
|
|
||||||
assert line1.slope() == float("inf")
|
|
||||||
assert line1.y_intercept() == 0
|
|
||||||
line2 = Line((1, 1), (2, 2))
|
|
||||||
assert line2.slope() == 1
|
|
||||||
assert line2.y_intercept() == 0
|
|
||||||
assert line2.equation() == "y = 1.0x"
|
|
||||||
line3 = Line((37, 5), (7, 29))
|
|
||||||
assert line3.slope() == -0.8
|
|
||||||
assert line3.y_intercept() == 34.6
|
|
||||||
assert line3.equation() == "y = -0.8x + 34.6"
|
|
||||||
assert (12, 25) in line3
|
|
||||||
assert (12, 12) not in line3
|
|
||||||
assert (3, 32.2) not in line3
|
|
||||||
assert line3.contains((6, 29.8), allow_on_extended=True) == True
|
|
||||||
assert line3.length()**2 == (37 - 7) ** 2 + (5 - 29) ** 2
|
|
||||||
|
|
@ -1,142 +0,0 @@
|
||||||
def point_maker(pre_point):
|
|
||||||
if isinstance(pre_point, Point):
|
|
||||||
return pre_point
|
|
||||||
elif isinstance(pre_point, tuple):
|
|
||||||
return Point(pre_point[0], pre_point[1])
|
|
||||||
else:
|
|
||||||
raise ValueError("Invalid input for Point")
|
|
||||||
|
|
||||||
|
|
||||||
class ShapeBase(object):
|
|
||||||
def __init__(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def show(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def move(self, dx, dy):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def set_color(self, color):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def get_color(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class Shape2D(ShapeBase):
|
|
||||||
def __init__(self, **kwargs):
|
|
||||||
super(Shape2D, self).__init__()
|
|
||||||
self.color = kwargs.get("color", "white")
|
|
||||||
self.fill = kwargs.get("fill", False)
|
|
||||||
self.width = kwargs.get("width", 1)
|
|
||||||
|
|
||||||
|
|
||||||
class Point(Shape2D):
|
|
||||||
def __init__(self, x, y):
|
|
||||||
super(Point, self).__init__()
|
|
||||||
self._x = x
|
|
||||||
self._y = y
|
|
||||||
|
|
||||||
@property
|
|
||||||
def x(self):
|
|
||||||
return self._x
|
|
||||||
|
|
||||||
@property
|
|
||||||
def y(self):
|
|
||||||
return self._y
|
|
||||||
|
|
||||||
|
|
||||||
class Line(Shape2D):
|
|
||||||
def __init__(self, point1, point2, **kwargs):
|
|
||||||
super(Line, self).__init__(**kwargs)
|
|
||||||
self.point1 = point_maker(point1)
|
|
||||||
self.point2 = point_maker(point2)
|
|
||||||
|
|
||||||
def contains(self, point, allow_on_extended=False):
|
|
||||||
"""判断点`point`是否在线段上
|
|
||||||
|
|
||||||
Args:
|
|
||||||
point (Point or tuple): 需要判断的点
|
|
||||||
allow_on_extended (bool, optional): 是否允许点在线段的延长线上. Defaults to False.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
_type_: boolean
|
|
||||||
"""
|
|
||||||
point = point_maker(point)
|
|
||||||
f = self.function()
|
|
||||||
if allow_on_extended:
|
|
||||||
return f(point.x) == point.y
|
|
||||||
else:
|
|
||||||
return f(point.x) == point.y and (
|
|
||||||
(point.x >= min(self.point1.x, self.point2.x) and point.x <= max(self.point1.x, self.point2.x)))
|
|
||||||
|
|
||||||
# 通过关键字`in`判断点是否在线段上
|
|
||||||
def __contains__(self, point):
|
|
||||||
return self.contains(point)
|
|
||||||
|
|
||||||
# 该线段所在直线的纵截距
|
|
||||||
def y_intercept(self):
|
|
||||||
if self.point1.x == self.point2.x:
|
|
||||||
return 0
|
|
||||||
return ((self.point1.y * self.point2.x) \
|
|
||||||
- (self.point1.x * self.point2.y)) \
|
|
||||||
/ (self.point2.x - self.point1.x)
|
|
||||||
|
|
||||||
# 该线段的斜率
|
|
||||||
def slope(self):
|
|
||||||
if self.point1.x - self.point2.x == 0:
|
|
||||||
return float("inf")
|
|
||||||
else:
|
|
||||||
return (self.point1.y - self.point2.y) / (self.point1.x - self.point2.x)
|
|
||||||
|
|
||||||
# 该线段所在直线的函数方程
|
|
||||||
def function(self):
|
|
||||||
a = self.slope()
|
|
||||||
b = self.y_intercept()
|
|
||||||
return lambda x: a * x + b
|
|
||||||
|
|
||||||
# 该线段的函数式
|
|
||||||
def equation(self):
|
|
||||||
if self.point1.x - self.point2.x == 0:
|
|
||||||
return "y = " + str(self.point1.y)
|
|
||||||
else:
|
|
||||||
a = self.slope()
|
|
||||||
b = self.y_intercept()
|
|
||||||
return f"y = {a}x{' + ' if b != 0 else ''}{b if b != 0 else ''}"
|
|
||||||
|
|
||||||
# 该线段的长度
|
|
||||||
def length(self):
|
|
||||||
return (
|
|
||||||
(self.point1.x - self.point2.x) ** 2 + (self.point1.y - self.point2.y) ** 2
|
|
||||||
) ** 0.5
|
|
||||||
|
|
||||||
# 该线段与另一线段的交点
|
|
||||||
def intersection(self, other):
|
|
||||||
if isinstance(other, Line):
|
|
||||||
if self.slope() == other.slope():
|
|
||||||
return None
|
|
||||||
else:
|
|
||||||
x = (
|
|
||||||
self.slope() * other.point1.x
|
|
||||||
- self.point1.y
|
|
||||||
+ other.slope() * self.point1.x
|
|
||||||
- other.point1.y
|
|
||||||
) / (self.slope() - other.slope())
|
|
||||||
y = self.slope() * (x - self.point1.x) + self.point1.y
|
|
||||||
return Point(x, y)
|
|
||||||
else:
|
|
||||||
raise ValueError("Invalid input for Line")
|
|
||||||
|
|
||||||
|
|
||||||
class Rectangle(Shape2D):
|
|
||||||
def __init__(self, point1, point2):
|
|
||||||
super(Rectangle, self).__init__()
|
|
||||||
if isinstance(point1, Point) and isinstance(point2, Point):
|
|
||||||
self.point1 = point1
|
|
||||||
self.point2 = point2
|
|
||||||
elif isinstance(point1, tuple) and isinstance(point2, tuple):
|
|
||||||
self.point1 = Point(point1[0], point1[1])
|
|
||||||
self.point2 = Point(point2[0], point2[1])
|
|
||||||
else:
|
|
||||||
raise ValueError("Invalid input for Rectangle")
|
|
||||||
Loading…
Reference in New Issue