add type hints for P3 & V3

This commit is contained in:
远野千束 2024-08-14 21:44:07 +08:00
parent 59d69f5fc1
commit 90fcee2ff9
10 changed files with 162 additions and 9 deletions

38
mbcp/mp_math/equation.py Normal file
View File

@ -0,0 +1,38 @@
# -*- coding: utf-8 -*-
"""
Copyright (C) 2020-2024 LiteyukiStudio. All Rights Reserved
@Time : 2024/8/9 上午11:32
@Author : snowykami
@Email : snowykami@outlook.com
@File : equation.py
@Software: PyCharm
"""
import numpy as np
from .point import Point3
from .mp_math_typing import ONE_VARIABLE_FUNC, TWO_VARIABLES_FUNC, THREE_VARIABLES_FUNC
class CurveEquation:
def __init__(self, x_func: ONE_VARIABLE_FUNC, y_func: ONE_VARIABLE_FUNC, z_func: ONE_VARIABLE_FUNC):
"""
曲线方程
:param x_func:
:param y_func:
:param z_func:
"""
self.x_func = x_func
self.y_func = y_func
self.z_func = z_func
def __call__(self, *t: float) -> "Point3" | tuple["Point3"]:
if len(t) == 1:
return Point3(self.x_func(t[0]), self.y_func(t[0]), self.z_func(t[0]))
else:
# np加速
...
def __str__(self):
return "CurveEquation()"

View File

@ -0,0 +1,18 @@
# -*- coding: utf-8 -*-
"""
Copyright (C) 2020-2024 LiteyukiStudio. All Rights Reserved
@Time : 2024/8/9 上午11:35
@Author : snowykami
@Email : snowykami@outlook.com
@File : mp_math_typing.py
@Software: PyCharm
"""
from typing import Callable, Iterable, TypeAlias
"""自变量"""
VAR: TypeAlias = float | Iterable[float] # 为后期支持多维矢量化做准备
ONE_VARIABLE_FUNC: TypeAlias = Callable[[VAR], float]
TWO_VARIABLES_FUNC: TypeAlias = Callable[[VAR, VAR], float]
THREE_VARIABLES_FUNC: TypeAlias = Callable[[VAR, VAR, VAR], float]

View File

@ -5,7 +5,7 @@ if TYPE_CHECKING:
class Point3: class Point3:
def __init__(self, x, y, z): def __init__(self, x: float, y: float, z: float):
""" """
笛卡尔坐标系中的点 笛卡尔坐标系中的点
:param x: :param x:

View File

@ -17,14 +17,14 @@ if TYPE_CHECKING:
class Segment3: class Segment3:
def __init__(self, start: "Point3", end: "Point3"): def __init__(self, p1: "Point3", p2: "Point3"):
""" """
三维空间中的线段 三维空间中的线段
:param start: :param p1:
:param end: :param p2:
""" """
self._start = start self._start = p1
self._end = end self._end = p2
"""方向向量""" """方向向量"""
self._direction = self._end - self._start self._direction = self._end - self._start

24
mbcp/mp_math/utils.py Normal file
View File

@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
"""
Copyright (C) 2020-2024 LiteyukiStudio. All Rights Reserved
@Time : 2024/8/12 下午9:16
@Author : snowykami
@Email : snowykami@outlook.com
@File : utils.py
@Software: PyCharm
"""
def clamp(x: float, min_: float, max_: float) -> float:
"""
区间截断函数
Args:
x:
min_:
max_:
Returns:
限制后的值
"""
return max(min(x, max_), min_)

View File

@ -1,11 +1,13 @@
from typing import overload, TYPE_CHECKING from typing import overload, TYPE_CHECKING
import numpy as np
if TYPE_CHECKING: if TYPE_CHECKING:
from .point import Point3 # type: ignore from .point import Point3 # type: ignore
class Vector3: class Vector3:
def __init__(self, x, y, z): def __init__(self, x: float, y: float, z: float):
""" """
笛卡尔坐标系中的向量 笛卡尔坐标系中的向量
:param x: :param x:
@ -72,6 +74,16 @@ class Vector3:
self._normalized = self / self.length self._normalized = self / self.length
return self._normalized return self._normalized
def normalize(self):
"""
自体归一化
"""
self._x /= self.length
self._y /= self.length
self._z /= self.length
self._length = 1
self._normalized = self
@overload @overload
def __add__(self, other: 'Vector3') -> 'Vector3': def __add__(self, other: 'Vector3') -> 'Vector3':
... ...
@ -81,6 +93,12 @@ class Vector3:
... ...
def __add__(self, other): def __add__(self, other):
"""
V + P -> P\n
V + V -> V
:param other:
:return:
"""
if isinstance(other, Vector3): 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): elif isinstance(other, Point3):
@ -89,6 +107,12 @@ class Vector3:
raise TypeError(f"unsupported operand type(s) for +: 'Vector3' and '{type(other)}'") raise TypeError(f"unsupported operand type(s) for +: 'Vector3' and '{type(other)}'")
def __radd__(self, other: 'Point3') -> 'Point3': def __radd__(self, other: 'Point3') -> 'Point3':
"""
P + V -> P\n
别去点那边实现了
:param other:
:return:
"""
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 @overload
@ -101,7 +125,7 @@ class Vector3:
def __sub__(self, other): def __sub__(self, other):
""" """
V - P -> P V - P -> P\n
V - V -> V V - V -> V
:param other: :param other:
:return: :return:

10
mbcp/particle/__init__.py Normal file
View File

@ -0,0 +1,10 @@
# -*- coding: utf-8 -*-
"""
Copyright (C) 2020-2024 LiteyukiStudio. All Rights Reserved
@Time : 2024/8/12 下午8:54
@Author : snowykami
@Email : snowykami@outlook.com
@File : __init__.py.py
@Software: PyCharm
"""

10
mbcp/presets/__init__.py Normal file
View File

@ -0,0 +1,10 @@
# -*- coding: utf-8 -*-
"""
Copyright (C) 2020-2024 LiteyukiStudio. All Rights Reserved
@Time : 2024/8/12 下午9:12
@Author : snowykami
@Email : snowykami@outlook.com
@File : __init__.py
@Software: PyCharm
"""

View File

@ -0,0 +1,28 @@
# -*- coding: utf-8 -*-
"""
几何模型点集
"""
import numpy as np
from mbcp.mp_math.point import Point3
from mbcp.mp_math.utils import clamp # type: ignore
class GeometricModels:
@staticmethod
def sphere(radius: float, density: float):
"""
生成球体上的点集
Args:
radius:
density:
Returns:
List[Point3]: 球体上的点集
"""
area = 4 * np.pi * radius ** 2 # 球表面积
num = int(area * density) # 粒子数
phi_list = np.arccos([clamp(-1 + ((2.0 * _ - 1.0) / num), -1, 1) for _ in range(num)])
theta_list = np.sqrt(num * np.pi) * phi_list
x_array = radius * np.sin(phi_list) * np.cos(theta_list)
y_array = radius * np.sin(phi_list) * np.sin(theta_list)
z_array = radius * np.cos(phi_list)
return [Point3(x_array[i], y_array[i], z_array[i]) for i in range(num)]

View File

@ -1 +1,2 @@
pytest~=8.3.2 pytest~=8.3.2
numpy~=2.0.1