Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implementing Line and Segment classes #54

Merged
merged 46 commits into from
Sep 8, 2022
Merged
Show file tree
Hide file tree
Changes from 41 commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
d6e2c7a
Include additional checks
RobPasMue Sep 5, 2022
a8f7b78
Small typos
RobPasMue Sep 5, 2022
afe3725
Rework the Line and Segment classes
RobPasMue Sep 5, 2022
1b33114
Remove lne from sketching (WIP)
RobPasMue Sep 5, 2022
3a6106e
Removing test_sketch module
RobPasMue Sep 5, 2022
6ae1ab2
Adding test_line module
RobPasMue Sep 5, 2022
1896eee
Pre-commit checks
RobPasMue Sep 5, 2022
19c773b
Typo
RobPasMue Sep 5, 2022
64590a1
Vector scalar multiplication
RobPasMue Sep 5, 2022
d74220c
Vector scalar multilication tests
RobPasMue Sep 5, 2022
3372c55
Line and segment bugs
RobPasMue Sep 5, 2022
a3c74a5
Line and segment tests
RobPasMue Sep 5, 2022
7d6e27f
Solving bugs + implementing error cases
RobPasMue Sep 5, 2022
b78851b
Pre-commit checks
RobPasMue Sep 5, 2022
8c4f724
Merge branch 'main' into feat/improve-line-segment
RobPasMue Sep 5, 2022
5df777a
Including version docstring
RobPasMue Sep 5, 2022
680da21
Typo
RobPasMue Sep 5, 2022
be92b26
Merge branch 'main' into feat/improve-line-segment
RobPasMue Sep 5, 2022
4c1408b
Code suggestions from @MaxJPRey and @Revathyvenugopal162
RobPasMue Sep 5, 2022
a39679a
Pre-commit checks
RobPasMue Sep 5, 2022
be97d1a
Merge branch 'main' into feat/improve-line-segment
RobPasMue Sep 5, 2022
51fecc9
Merge branch 'main' into feat/improve-line-segment
RobPasMue Sep 7, 2022
8ba272a
Adapting to main branch
RobPasMue Sep 7, 2022
fd60bbc
Class calls broken in docs
RobPasMue Sep 7, 2022
cc62f2e
Merge branch 'main' into feat/improve-line-segment
RobPasMue Sep 7, 2022
1bdb31b
Improved docstrings for shapes
RobPasMue Sep 7, 2022
ffe256a
New checks and testing
RobPasMue Sep 7, 2022
726e605
Adding fundamental direction unit vectors
RobPasMue Sep 7, 2022
19579a2
Adding base unit property to QuantityVectorXD
RobPasMue Sep 7, 2022
4e214e2
Adapting shape classes and docstrings
RobPasMue Sep 7, 2022
fb66ba2
Testing base_unit property for QuantityVectorXD objects
RobPasMue Sep 7, 2022
af704eb
Redoing line implementation
RobPasMue Sep 7, 2022
b2fac07
Testing line
RobPasMue Sep 7, 2022
bb174ea
Adapting sketch to support lines and segments
RobPasMue Sep 7, 2022
56638c5
Update src/ansys/geometry/core/misc/__init__.py
RobPasMue Sep 7, 2022
e2dbd5f
Update src/ansys/geometry/core/misc/checks.py
RobPasMue Sep 7, 2022
ae0358d
Better tests for certain checks
RobPasMue Sep 7, 2022
593973e
Pre-commit
RobPasMue Sep 7, 2022
4bcd945
Merge branch 'feat/improve-line-segment' of https://github.com/pyansy…
RobPasMue Sep 7, 2022
1ef6a63
Apply suggestions from code review
RobPasMue Sep 7, 2022
45f91bf
Typo in modeling
RobPasMue Sep 7, 2022
51d40d7
Zero-valued ndarray message
RobPasMue Sep 7, 2022
33d1404
Code suggestions @MaxJPRey
RobPasMue Sep 7, 2022
b59f7c0
Code suggestions and testing
RobPasMue Sep 8, 2022
ad2586e
Pre-commit
RobPasMue Sep 8, 2022
dc797c4
Remove unnecessary code
RobPasMue Sep 8, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions src/ansys/geometry/core/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import importlib_metadata

__version__ = importlib_metadata.version(__name__.replace(".", "-"))
"""The installed version of PyGeometry."""


# Units
Expand Down
9 changes: 9 additions & 0 deletions src/ansys/geometry/core/math/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,12 @@
"Vector2D",
"Vector3D",
]

UNIT_VECTOR_X = UnitVector3D([1, 0, 0])
"""Unit vector in the cartesian traditional X direction. """

UNIT_VECTOR_Y = UnitVector3D([0, 1, 0])
"""Unit vector in the cartesian traditional Y direction. """

UNIT_VECTOR_Z = UnitVector3D([0, 0, 1])
"""Unit vector in the cartesian traditional Z direction. """
44 changes: 35 additions & 9 deletions src/ansys/geometry/core/math/vector.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,15 +94,23 @@ def __ne__(self, other: "Vector3D") -> bool:
"""Not equals operator for ``Vector3D``."""
return not self == other

def __mul__(self, other: "Vector3D") -> Real:
"""Overload * operator with dot product."""
check_type_equivalence(other, self)
return self.dot(other)
def __mul__(self, other: Union["Vector3D", Real]) -> Union["Vector3D", Real]:
"""Overload * operator with dot product.

Note
----
Also admits scalar multiplication.
"""
if isinstance(other, (int, float)):
return np.multiply(self, other).view(self.__class__)
else:
check_type_equivalence(other, self)
return self.dot(other)

def __mod__(self, other: "Vector3D") -> "Vector3D":
"""Overload % operator with cross product."""
check_type_equivalence(other, self)
return self.cross(other)
return self.cross(other).view(self.__class__)


class Vector2D(np.ndarray):
Expand Down Expand Up @@ -168,10 +176,18 @@ def __ne__(self, other: "Vector2D") -> bool:
"""Not equals operator for ``Vector2D``."""
return not self == other

def __mul__(self, other: "Vector2D") -> Real:
"""Overload * operator with dot product."""
check_type_equivalence(other, self)
return self.dot(other)
def __mul__(self, other: Union["Vector2D", Real]) -> Union["Vector2D", Real]:
"""Overload * operator with dot product.

Note
----
Also admits scalar multiplication.
"""
if isinstance(other, (int, float)):
return np.multiply(self, other).view(self.__class__)
else:
check_type_equivalence(other, self)
return self.dot(other)


class UnitVector3D(Vector3D):
Expand Down Expand Up @@ -296,6 +312,11 @@ def unit(self, unit: Unit) -> None:
check_pint_unit_compatibility(unit, self._base_unit)
self._unit = unit

@property
def base_unit(self) -> Unit:
"""Returns the base unit of the ``QuantityVector3D``."""
return self._base_unit

def normalize(self) -> "QuantityVector3D":
"""Return a normalized version of the ``QuantityVector3D``"""
vec = Vector3D.normalize(self).view(QuantityVector3D)
Expand Down Expand Up @@ -388,6 +409,11 @@ def unit(self) -> Unit:
"""Returns the unit of the ``QuantityVector2D``."""
return self._unit

@property
def base_unit(self) -> Unit:
"""Returns the base unit of the ``QuantityVector2D``."""
return self._base_unit
RobPasMue marked this conversation as resolved.
Show resolved Hide resolved

@unit.setter
def unit(self, unit: Unit) -> None:
"""Sets the unit of the ``QuantityVector2D``."""
Expand Down
14 changes: 13 additions & 1 deletion src/ansys/geometry/core/misc/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,27 @@
from ansys.geometry.core.misc.checks import (
check_is_float_int,
check_is_pint_unit,
check_is_point,
check_is_quantityvector,
check_is_unitvector,
check_is_vector,
check_ndarray_is_float_int,
check_ndarray_is_non_zero,
check_ndarray_is_not_none,
check_pint_unit_compatibility,
check_type_equivalence,
)

__all__ = [
"check_is_float_int",
"check_is_pint_unit",
"check_is_point",
"check_is_quantityvector",
"check_is_unitvector",
"check_is_vector",
"check_ndarray_is_float_int",
"check_ndarray_is_not_none",
"check_ndarray_is_non_zero",
"check_pint_unit_compatibility",
"check_type_equivalence",
"check_ndarray_is_float_int",
]
182 changes: 182 additions & 0 deletions src/ansys/geometry/core/misc/checks.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,134 @@ def check_is_float_int(param: object, param_name: Optional[Union[str, None]] = N
)


def check_is_point(
RobPasMue marked this conversation as resolved.
Show resolved Hide resolved
param: object, param_name: Optional[Union[str, None]] = None, only_3d: bool = False
RobPasMue marked this conversation as resolved.
Show resolved Hide resolved
) -> None:
"""
Checks if the parameter provided is a ``Point3D`` or ``Point2D``.

Parameters
----------
param : object
Object instance to be checked.
param_name : str or None, optional
The object instance name (if any). By default, ``None``.
only_3d : bool
Only consider ``Point3D`` for checking.

Raises
------
TypeError
In case the parameter is not a ``Point3D`` or a ``Point2D``.
"""
from ansys.geometry.core.math.point import Point2D, Point3D

consider = (Point3D) if only_3d else (Point2D, Point3D)
point_type = "Point3D" if only_3d else "Point3D or Point2D"
if not isinstance(param, consider):
raise TypeError(
f"The parameter provided should be a {point_type} object."
if param_name is None
else f"The parameter '{param_name}' should be a {point_type} object."
)


def check_is_vector(
param: object, param_name: Optional[Union[str, None]] = None, only_3d: bool = False
RobPasMue marked this conversation as resolved.
Show resolved Hide resolved
) -> None:
"""
Checks if the parameter provided is a ``Vector3D`` or ``Vector2D``.

Parameters
----------
param : object
Object instance to be checked.
param_name : str or None, optional
The object instance name (if any). By default, ``None``.
only_3d : bool
Only consider ``Vector3D`` for checking.

Raises
------
TypeError
In case the parameter is not a ``Vector3D`` or a ``Vector2D``.
"""
from ansys.geometry.core.math.vector import Vector2D, Vector3D

consider = (Vector3D) if only_3d else (Vector2D, Vector3D)
vector_type = "Vector3D" if only_3d else "Vector3D or Vector2D"
if not isinstance(param, consider):
raise TypeError(
f"The parameter provided should be a {vector_type} object."
if param_name is None
else f"The parameter '{param_name}' should be a {vector_type} object."
)


def check_is_unitvector(
param: object, param_name: Optional[Union[str, None]] = None, only_3d: bool = False
) -> None:
"""
Checks if the parameter provided is a ``UnitVector3D`` or ``UnitVector2D``.

Parameters
----------
param : object
Object instance to be checked.
param_name : str or None, optional
The object instance name (if any). By default, ``None``.
only_3d : bool
Only consider ``UnitVector3D`` for checking.

Raises
------
TypeError
In case the parameter is not a ``UnitVector3D`` or a ``UnitVector2D``.
"""
from ansys.geometry.core.math.vector import UnitVector2D, UnitVector3D

consider = (UnitVector3D) if only_3d else (UnitVector2D, UnitVector3D)
unit_vector_type = "UnitVector3D" if only_3d else "UnitVector3D or UnitVector2D"
if not isinstance(param, consider):
raise TypeError(
f"The parameter provided should be a {unit_vector_type} object."
if param_name is None
else f"The parameter '{param_name}' should be a {unit_vector_type} object."
)


def check_is_quantityvector(
param: object, param_name: Optional[Union[str, None]] = None, only_3d: bool = False
) -> None:
"""
Checks if the parameter provided is a ``QuantityVector3D`` or ``QuantityVector2D``.

Parameters
----------
param : object
Object instance to be checked.
param_name : str or None, optional
The object instance name (if any). By default, ``None``.
only_3d : bool
Only consider ``QuantityVector3D`` for checking.

Raises
------
TypeError
In case the parameter is not a ``QuantityVector3D`` or a ``QuantityVector2D``.
"""
from ansys.geometry.core.math.vector import QuantityVector2D, QuantityVector3D

consider = (QuantityVector3D) if only_3d else (QuantityVector2D, QuantityVector3D)
quantity_vector_type = "QuantityVector3D" if only_3d else "QuantityVector3D or QuantityVector2D"
if not isinstance(param, consider):
raise TypeError(
f"The parameter provided should be a {quantity_vector_type} object."
if param_name is None
else f"The parameter '{param_name}' should be a {quantity_vector_type} object."
)


def check_ndarray_is_float_int(
param: np.ndarray, param_name: Optional[Union[str, None]] = None
) -> None:
Expand Down Expand Up @@ -60,6 +188,60 @@ def check_ndarray_is_float_int(
)


def check_ndarray_is_not_none(
param: np.ndarray, param_name: Optional[Union[str, None]] = None
) -> None:
"""
Checks if the :class:`numpy.ndarray` is not None-valued.

Parameters
----------
param : ~numpy.ndarray
:class:`numpy.ndarray` instance to be checked.
param_name : str or None, optional
The :class:`numpy.ndarray` instance name (if any). By default, ``None``.

Raises
------
ValueError
In case the :class:`numpy.ndarray` is None-valued.
"""
param_data = np.ravel(param)
if all(value is None for value in param_data):
raise ValueError(
f"The numpy.ndarray provided should not be a None numpy.ndarray."
if param_name is None
else f"The numpy.ndarray '{param_name}' should not be a None numpy.ndarray."
)


def check_ndarray_is_non_zero(
param: np.ndarray, param_name: Optional[Union[str, None]] = None
) -> None:
"""
Checks if the :class:`numpy.ndarray` is not zero-valued.

Parameters
----------
param : ~numpy.ndarray
:class:`numpy.ndarray` instance to be checked.
param_name : str or None, optional
The :class:`numpy.ndarray` instance name (if any). By default, ``None``.

Raises
------
ValueError
In case the :class:`numpy.ndarray` is zero-valued.
"""
param_data = np.ravel(param)
if all(value == 0 for value in param_data):
raise ValueError(
f"The numpy.ndarray provided should not be a zeroes numpy.ndarray."
if param_name is None
else f"The numpy.ndarray '{param_name}' should not be a zeroes numpy.ndarray."
RobPasMue marked this conversation as resolved.
Show resolved Hide resolved
)


def check_is_pint_unit(param: object, param_name: Optional[Union[str, None]] = None) -> None:
"""
Checks if the parameter provided is a :class:`pint.Unit`.
Expand Down
4 changes: 2 additions & 2 deletions src/ansys/geometry/core/shapes/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
from ansys.geometry.core.shapes.base import BaseShape
from ansys.geometry.core.shapes.circle import CircleShape
from ansys.geometry.core.shapes.ellipse import EllipseShape
from ansys.geometry.core.shapes.line import LineShape
from ansys.geometry.core.shapes.line import LineShape, SegmentShape

__all__ = ["BaseShape", "CircleShape", "EllipseShape", "LineShape"]
__all__ = ["BaseShape", "CircleShape", "EllipseShape", "LineShape", "SegmentShape"]