add some mathematical method for object Line3

This commit is contained in:
远野千束 2024-08-07 00:10:07 +08:00
parent de5bfa3843
commit 24d8b4980d
8 changed files with 104 additions and 72 deletions

88
mbcp/mp_math/line.py Normal file
View File

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

View File

@ -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:

0
mbcp/mp_math/py.typed Normal file
View File

View File

@ -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'")

View File

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