diff --git a/mbcp/mp_math/equation.py b/mbcp/mp_math/equation.py new file mode 100644 index 0000000..e6a2a03 --- /dev/null +++ b/mbcp/mp_math/equation.py @@ -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()" diff --git a/mbcp/mp_math/mp_math_typing.py b/mbcp/mp_math/mp_math_typing.py new file mode 100644 index 0000000..6ee2c73 --- /dev/null +++ b/mbcp/mp_math/mp_math_typing.py @@ -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] diff --git a/mbcp/mp_math/point.py b/mbcp/mp_math/point.py index 5fe7b84..bfd5ed6 100644 --- a/mbcp/mp_math/point.py +++ b/mbcp/mp_math/point.py @@ -5,7 +5,7 @@ if TYPE_CHECKING: class Point3: - def __init__(self, x, y, z): + def __init__(self, x: float, y: float, z: float): """ 笛卡尔坐标系中的点。 :param x: diff --git a/mbcp/mp_math/segment.py b/mbcp/mp_math/segment.py index db3f328..d4d3afa 100644 --- a/mbcp/mp_math/segment.py +++ b/mbcp/mp_math/segment.py @@ -17,14 +17,14 @@ if TYPE_CHECKING: class Segment3: - def __init__(self, start: "Point3", end: "Point3"): + def __init__(self, p1: "Point3", p2: "Point3"): """ 三维空间中的线段。 - :param start: - :param end: + :param p1: + :param p2: """ - self._start = start - self._end = end + self._start = p1 + self._end = p2 """方向向量""" self._direction = self._end - self._start diff --git a/mbcp/mp_math/utils.py b/mbcp/mp_math/utils.py new file mode 100644 index 0000000..4a6b795 --- /dev/null +++ b/mbcp/mp_math/utils.py @@ -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_) diff --git a/mbcp/mp_math/vector.py b/mbcp/mp_math/vector.py index 5ab7995..fa987fd 100644 --- a/mbcp/mp_math/vector.py +++ b/mbcp/mp_math/vector.py @@ -1,11 +1,13 @@ from typing import overload, TYPE_CHECKING +import numpy as np + if TYPE_CHECKING: from .point import Point3 # type: ignore class Vector3: - def __init__(self, x, y, z): + def __init__(self, x: float, y: float, z: float): """ 笛卡尔坐标系中的向量。 :param x: @@ -72,6 +74,16 @@ class Vector3: self._normalized = self / self.length 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 def __add__(self, other: 'Vector3') -> 'Vector3': ... @@ -81,6 +93,12 @@ class Vector3: ... def __add__(self, other): + """ + V + P -> P\n + 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): @@ -89,6 +107,12 @@ class Vector3: raise TypeError(f"unsupported operand type(s) for +: 'Vector3' and '{type(other)}'") 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) @overload @@ -101,7 +125,7 @@ class Vector3: def __sub__(self, other): """ - V - P -> P + V - P -> P\n V - V -> V :param other: :return: diff --git a/mbcp/particle/__init__.py b/mbcp/particle/__init__.py new file mode 100644 index 0000000..9e19d4c --- /dev/null +++ b/mbcp/particle/__init__.py @@ -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 +""" \ No newline at end of file diff --git a/mbcp/presets/__init__.py b/mbcp/presets/__init__.py new file mode 100644 index 0000000..f5f59a1 --- /dev/null +++ b/mbcp/presets/__init__.py @@ -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 +""" \ No newline at end of file diff --git a/mbcp/presets/model/__init__.py b/mbcp/presets/model/__init__.py new file mode 100644 index 0000000..26c7333 --- /dev/null +++ b/mbcp/presets/model/__init__.py @@ -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)] diff --git a/requirements.txt b/requirements.txt index df16fec..a2325b4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1,2 @@ -pytest~=8.3.2 \ No newline at end of file +pytest~=8.3.2 +numpy~=2.0.1 \ No newline at end of file