add some mathematical method for object Segment3

This commit is contained in:
远野千束 2024-08-07 00:54:13 +08:00
parent b4d5da5fc3
commit edc6a5ddaf
7 changed files with 243 additions and 24 deletions

View File

@ -8,10 +8,10 @@ Copyright (C) 2020-2024 LiteyukiStudio. All Rights Reserved
@File : line.py
@Software: PyCharm
"""
from typing import overload, TYPE_CHECKING
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from .point import Point3
from .point import Point3 # type: ignore
class Line3:
@ -49,8 +49,6 @@ class Line3:
: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.")

View File

@ -1,7 +1,7 @@
from typing import overload, TYPE_CHECKING
from typing import TYPE_CHECKING, overload
if TYPE_CHECKING: # type: ignore
from .vector import Vector3
if TYPE_CHECKING:
from .vector import Vector3 # type: ignore
class Point3:
@ -19,5 +19,37 @@ class Point3:
def __str__(self):
return f"Point3({self.x}, {self.y}, {self.z})"
@overload
def __add__(self, other: "Vector3") -> "Point3":
...
@overload
def __add__(self, other: "Point3") -> "Point3":
...
def __add__(self, other):
"""
P + V -> P
P + P -> P
:param other:
:return:
"""
return Point3(self.x + other.x, self.y + other.y, self.z + other.z)
def __sub__(self, other: "Point3") -> "Vector3":
"""
P - P -> V
P - V -> P 已在 :class:`Vector3` 中实现
:param other:
:return:
"""
return Vector3(self.x - other.x, self.y - other.y, self.z - other.z)
def __truediv__(self, other: float) -> "Point3":
"""
P / n -> P
:param other:
:return:
"""
return Point3(self.x / other, self.y / other, self.z / other)

View File

@ -0,0 +1,2 @@
# py.typed
partial

90
mbcp/mp_math/segment.py Normal file
View File

@ -0,0 +1,90 @@
# -*- coding: utf-8 -*-
"""
Copyright (C) 2020-2024 LiteyukiStudio. All Rights Reserved
@Time : 2024/8/7 上午12:42
@Author : snowykami
@Email : snowykami@outlook.com
@File : segment.py
@Software: PyCharm
"""
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from .point import Point3 # type: ignore
from .vector import Vector3 # type: ignore
class Segment3:
def __init__(self, start: "Point3", end: "Point3"):
"""
三维空间中的线段
:param start:
:param end:
"""
self._start = start
self._end = end
"""方向向量"""
self._direction = self._end - self._start
"""长度"""
self._length = self._direction.length
"""中心点"""
self._midpoint = (self._start + self._end) / 2
def __str__(self):
return f"Segment3({self._start}, {self._end})"
def _unset_properties(self):
self._length = None
self._direction = None
self._midpoint = None
@property
def start(self) -> "Point3":
return self._start
@start.setter
def start(self, value: "Point3"):
self._start = value
self._unset_properties()
@property
def end(self) -> "Point3":
return self._end
@end.setter
def end(self, value: "Point3"):
self._end = value
self._unset_properties()
@property
def length(self) -> float:
"""
线段的长度
:return:
"""
if self._length is None:
self._length = (self._end - self._start).length
return self._length
@property
def direction(self) -> "Vector3":
"""
线段的方向向量
:return:
"""
if self._direction is None:
self._direction = self._end - self._start
return self._direction
@property
def midpoint(self) -> "Point3":
"""
线段的中点
:return:
"""
if self._midpoint is None:
self._midpoint = (self._start + self._end) / 2
return self._midpoint

View File

@ -1,7 +1,7 @@
from typing import overload, TYPE_CHECKING
if TYPE_CHECKING: # type: ignore
from .point import Point3
if TYPE_CHECKING:
from .point import Point3 # type: ignore
class Vector3:
@ -12,12 +12,65 @@ class Vector3:
:param y:
:param z:
"""
self.x = x
self.y = y
self.z = z
self._x = x
self._y = y
self._z = z
self._length = (x ** 2 + y ** 2 + z ** 2) ** 0.5
self._normalized = self / self._length
def __str__(self):
return f"Vector3({self.x}, {self.y}, {self.z})"
return f"Vector3({self._x}, {self._y}, {self._z})"
def _unset_properties(self):
self._length = None
self._normalized = None
@property
def x(self):
return self._x
@x.setter
def x(self, value):
self._x = value
self._unset_properties()
@property
def y(self):
return self._y
@y.setter
def y(self, value):
self._y = value
self._unset_properties()
@property
def z(self):
return self._z
@z.setter
def z(self, value):
self._z = value
self._unset_properties()
@property
def length(self) -> float:
"""
向量的模
:return:
"""
if self._length is None:
self._length = (self._x ** 2 + self._y ** 2 + self._z ** 2) ** 0.5
return self._length
@property
def normalized(self) -> 'Vector3':
"""
返回该向量的单位向量
:return:
"""
if self._normalized is None:
self._normalized = self / self.length
return self._normalized
@overload
def __add__(self, other: 'Vector3') -> 'Vector3':
@ -29,14 +82,14 @@ class Vector3:
def __add__(self, other):
if isinstance(other, Vector3):
return Vector3(self.x + other.x, self.y + other.y, self.z + other.z)
return Vector3(self._x + other._x, self._y + other._y, self._z + other._z)
elif isinstance(other, Point3):
return Point3(self.x + other.x, self.y + other.y, self.z + other.z)
return Point3(self._x + other.x, self._y + other.y, self._z + other.z)
else:
raise TypeError(f"unsupported operand type(s) for +: 'Vector3' and '{type(other)}'")
def __radd__(self, other: 'Point3') -> 'Point3':
return Point3(self.x + other.x, self.y + other.y, self.z + other.z)
return Point3(self._x + other.x, self._y + other.y, self._z + other.z)
@overload
def __sub__(self, other: 'Vector3') -> 'Vector3':
@ -54,9 +107,9 @@ class Vector3:
:return:
"""
if isinstance(other, Vector3):
return Vector3(self.x - other.x, self.y - other.y, self.z - other.z)
return Vector3(self._x - other._x, self._y - other._y, self._z - other._z)
elif isinstance(other, Point3):
return Point3(self.x - other.x, self.y - other.y, self.z - other.z)
return Point3(self._x - other.x, self._y - other.y, self._z - other.z)
else:
raise TypeError(f"unsupported operand type(s) for -: 'Vector3' and '{type(other)}'")
@ -68,6 +121,48 @@ class Vector3:
"""
if isinstance(other, Point3):
return Point3(other.x - self.x, other.y - self.y, other.z - self.z)
return Point3(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'")
@overload
def __mul__(self, other: float) -> 'Vector3':
...
@overload
def __mul__(self, other: 'Vector3') -> float:
...
def __mul__(self, other):
"""
乘法包括点乘和数乘
:param other:
:return:
"""
if isinstance(other, (int, float)):
return Vector3(self._x * other, self._y * other, self._z * other)
elif isinstance(other, Vector3):
return self._x * other._x + self._y * other._y + self._z * other._z
else:
raise TypeError(f"unsupported operand type(s) for *: 'Vector3' and '{type(other)}'")
def __rmul__(self, other: float) -> 'Vector3':
"""
右乘
:param other:
:return:
"""
return Vector3(self._x * other, self._y * other, self._z * other)
def __matmul__(self, other: 'Vector3') -> 'Vector3':
"""
叉乘
:param other: 另一个向量
:return: 叉乘结果向量
"""
return Vector3(self._y * other._z - self._z * other._y,
self._z * other._x - self._x * other._z,
self._x * other._y - self._y * other._x)
def __truediv__(self, other: float) -> 'Vector3':
return Vector3(self._x / other, self._y / other, self._z / other)

2
mbcp/py.typed Normal file
View File

@ -0,0 +1,2 @@
# py.typed
partial

View File

@ -8,15 +8,15 @@ Copyright (C) 2020-2024 LiteyukiStudio. All Rights Reserved
@File : test_vector.py
@Software: PyCharm
"""
from mcpe.mp_math.vector import Vector3
from mcpe.mp_math.point import Point3
from mbcp.mp_math.vector import Vector3
from mbcp.mp_math.point import Point3
def test_v():
v1 = Vector3(1, 2, 3)
v2 = Vector3(4, 5, 6)
v3 = v1 + v2
assert v3.x == 5
assert v3.y == 7
assert v3.z == 9
assert v3._x == 5
assert v3._y == 7
assert v3._z == 9
print("test_v 1111passed")