diff --git a/mcpe/__init__.py b/mbcp/__init__.py similarity index 100% rename from mcpe/__init__.py rename to mbcp/__init__.py diff --git a/mcpe/mp_math/__init__.py b/mbcp/mp_math/__init__.py similarity index 100% rename from mcpe/mp_math/__init__.py rename to mbcp/mp_math/__init__.py diff --git a/mbcp/mp_math/line.py b/mbcp/mp_math/line.py new file mode 100644 index 0000000..b52986c --- /dev/null +++ b/mbcp/mp_math/line.py @@ -0,0 +1,88 @@ +# -*- coding: utf-8 -*- +""" +Copyright (C) 2020-2024 LiteyukiStudio. All Rights Reserved + +@Time : 2024/8/6 下午12:57 +@Author : snowykami +@Email : snowykami@outlook.com +@File : line.py +@Software: PyCharm +""" +from typing import overload, TYPE_CHECKING + +if TYPE_CHECKING: + from .point import Point3 + + +class Line3: + def __init__(self, a: float, b: float, c: float, d: float): + """ + 三维空间中的直线。 + :param a: + :param b: + :param c: + :param d: + """ + self.a = a + self.b = b + self.c = c + self.d = d + + def __str__(self): + return f"Line3({self.a}, {self.b}, {self.c}, {self.d})" + + def get_perpendicular(self, point: "Point3") -> "Line3": + """ + 获取直线经过指定点p的垂线。 + :param point: 指定点p,直线外的点 + :return: 垂直于self且过点p的直线 + """ + a = -self.b + b = self.a + c = 0 + d = -(a * point.x + b * point.y + self.c * point.z) + return Line3(a, b, c, d) + + def get_intersection(self, line: "Line3") -> "Point3": + """ + 获取两条直线的交点。 + :param line: + :return: + """ + normal1 = (self.b, -self.a, 0) + normal2 = (-line.b, line.a, 0) + + if self.is_parallel(line): + raise ValueError("Lines are parallel and do not intersect.") + + if self.is_collinear(line): + raise ValueError("Lines are collinear and do not have a single intersection point.") + + if not self.is_coplanar(line): + raise ValueError("Lines are not coplanar and do not intersect.") + + a1, b1, c1, d1 = self.a, self.b, self.c, self.d + a2, b2, c2, d2 = line.a, line.b, line.c, line.d + + t = (b1 * (c2 * d1 - c1 * d2) - b2 * (c1 * d1 - c2 * d2)) / (b1 * c2 - b2 * c1) + + x = self.a * t + self.b * (-d1 / self.b) + y = -self.b * t + self.a * (d1 / self.a) + z = 0 + + return Point3(x, y, z) + + def is_parallel(self, line: "Line3") -> bool: + # 直线平行的条件是它们的法向量成比例 + return self.a * line.b == self.b * line.a and self.c * line.b == self.d * line.a + + def is_collinear(self, line: "Line3") -> bool: + # 直线共线的条件是它们的法向量成比例且常数项也成比例 + return self.is_parallel(line) and (self.d * line.b - self.b * line.d) / (self.a * line.b - self.b * line.a) == 0 + + def is_coplanar(self, line: "Line3") -> bool: + # 两条直线共面的条件是它们的方向向量和法向量的叉乘为零向量 + direction1 = (-self.c, 0, self.a) + direction2 = (line.c, -line.b, 0) + cross_product = direction1[0] * direction2[1] - direction1[1] * direction2[0] + return cross_product == 0 diff --git a/mcpe/mp_math/plane.py b/mbcp/mp_math/plane.py similarity index 100% rename from mcpe/mp_math/plane.py rename to mbcp/mp_math/plane.py diff --git a/mcpe/mp_math/point.py b/mbcp/mp_math/point.py similarity index 87% rename from mcpe/mp_math/point.py rename to mbcp/mp_math/point.py index edfbf87..8a729f9 100644 --- a/mcpe/mp_math/point.py +++ b/mbcp/mp_math/point.py @@ -1,7 +1,7 @@ from typing import overload, TYPE_CHECKING -if TYPE_CHECKING: - from mcpe.mp_math.vector import Vector3 +if TYPE_CHECKING: # type: ignore + from .vector import Vector3 class Point3: diff --git a/mbcp/mp_math/py.typed b/mbcp/mp_math/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/mcpe/mp_math/vector.py b/mbcp/mp_math/vector.py similarity index 88% rename from mcpe/mp_math/vector.py rename to mbcp/mp_math/vector.py index 5e8f520..b96dea2 100644 --- a/mcpe/mp_math/vector.py +++ b/mbcp/mp_math/vector.py @@ -1,7 +1,7 @@ from typing import overload, TYPE_CHECKING -if TYPE_CHECKING: - from mcpe.mp_math.point import Point3 +if TYPE_CHECKING: # type: ignore + from .point import Point3 class Vector3: @@ -47,6 +47,12 @@ class Vector3: ... def __sub__(self, other): + """ + V - P -> P + V - V -> V + :param other: + :return: + """ if isinstance(other, Vector3): return Vector3(self.x - other.x, self.y - other.y, self.z - other.z) elif isinstance(other, Point3): @@ -55,9 +61,13 @@ class Vector3: raise TypeError(f"unsupported operand type(s) for -: 'Vector3' and '{type(other)}'") def __rsub__(self, other: Point3): + """ + P - V -> P + :param other: + :return: + """ + if isinstance(other, Point3): return Point3(other.x - self.x, other.y - self.y, other.z - self.z) - elif isinstance(other, Vector3): - return Vector3(other.x - self.x, other.y - self.y, other.z - self.z) else: raise TypeError(f"unsupported operand type(s) for -: '{type(other)}' and 'Vector3'") diff --git a/mcpe/mp_math/line.py b/mcpe/mp_math/line.py deleted file mode 100644 index 4005fd1..0000000 --- a/mcpe/mp_math/line.py +++ /dev/null @@ -1,66 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Copyright (C) 2020-2024 LiteyukiStudio. All Rights Reserved - -@Time : 2024/8/6 下午12:57 -@Author : snowykami -@Email : snowykami@outlook.com -@File : line.py -@Software: PyCharm -""" -from typing import overload, TYPE_CHECKING - -if TYPE_CHECKING: - from mcpe.mp_math.point import Point3 - from mcpe.mp_math.vector import Vector3 - - -class Line3: - def __init__(self, a: float, b: float, c: float, d:float): - """ - 三维空间中的直线。 - :param a: - :param b: - :param c: - :param d: - """ - self.a = a - self.b = b - self.c = c - self.d = d - - def __str__(self): - return f"Line3({self.a}, {self.b}, {self.c}, {self.d})" - - def get_perpendicular(self, p: "Point3") -> "Line3": - """ - 获取直线经过指定点p的垂线。 - :param p: 指定点p,直线外的点 - :return: 垂直于self且过点p的直线 - """ - a = -self.b - b = self.a - c = 0 - d = -(a * p.x + b * p.y + self.c * p.z) - return Line3(a, b, c, d) - - def get_intersection(self, l: "Line3") -> "Point3": - """ - 获取两空间直线的交点。 - :param l: 另一条直线,不平行于self,不共线,且共面 - :return: 交点 - """ - # 平行检测 - if ...: - ... - # 共线检测 - if ...: - ... - # 不共线检测 - if ...: - ... - - - - -