Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .claude/settings.local.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"permissions": {
"allow": [
"Bash(python:*)"
],
"deny": [],
"ask": []
}
}
2 changes: 2 additions & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
PYTHON=python3
VENV=/tmp/pipTest
157 changes: 157 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# Cython and C extensions
*.c
*.so
*.pyd
*.dll

# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
*.egg-info/
.installed.cfg
*.egg
MANIFEST

# PyInstaller
# Usually contains a dist/ folder and build/ artifacts
*.manifest
*.spec

# PyBuilder
target/

# Virtual environments
.env/
.venv/
env/
venv/
ENV/
env.bak/
venv.bak/

# pipenv
Pipfile.lock

# poetry
poetry.lock

# hatch
*.hatch/

# pdm
__pypackages__/

# tox and nox
.tox/
.nox/

# pytest
.cache/
.pytest_cache/

# mypy
.mypy_cache/
.dmypy.json
dmypy.json

# coverage and test reports
.coverage
.coverage.*
nosetests.xml
coverage.xml
*.cover
.hypothesis/

# Pyre type checker
.pyre/

# CMake files
CMakeFiles/
CMakeCache.txt
cmake_install.cmake


# Translations
*.mo
*.pot

# Django stuff
*.log
local_settings.py
db.sqlite3

# Flask stuff
instance/
.webassets-cache

# Scrapy stuff
.scrapy

# IPython / Jupyter
.ipynb_checkpoints/
profile

# macOS system files
*.DS_Store
.AppleDouble
.LSOverride

# Thumbnails and metadata
._*

# Files that might appear in root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent

# Directories created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/

# Sphinx documentation build
docs/_build/

# IDEs and editors
# IntelliJ IDEA family
.idea/
*.iml
*.ipr
*.iws
.idea_modules/

# Visual Studio Code
.vscode/

# Cookiecutter
output/
python_boilerplate/
cookiecutter-pypackage-env/
34 changes: 34 additions & 0 deletions .pylintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# https://pylint.readthedocs.io/en/v2.12.2/user_guide/options.html

[BASIC]
module-naming-style=any
const-naming-style=any
class-naming-style=any
function-naming-style=any
method-naming-style=any
attr-naming-style=any
argument-naming-style=any
variable-naming-style=any
class-attribute-naming-style=any
class-const-naming-style=any
inlinevar-naming-style=any

# Custom regexes to allow both snake_case and camelCase
module-rgx=(?:(?P<snake>[a-z_][a-z0-9_]+)|(?P<camel>[a-z]+(?:[A-Z][a-z0-9]*)*))$
const-rgx=(?:(?P<snake>[A-Z_][A-Z0-9_]*)|(?P<camel>[A-Z][a-zA-Z0-9]*))$
class-rgx=(?:(?P<camel>[A-Z][a-zA-Z0-9]*)|(?P<snake>[a-z_][a-z0-9_]+))$
function-rgx=(?:(?P<snake>[a-z_][a-z0-9_]*)|(?P<camel>[a-z]+(?:[A-Z][a-z0-9]*)*))$
method-rgx=(?:(?P<snake>[a-z_][a-z0-9_]*)|(?P<camel>[a-z]+(?:[A-Z][a-z0-9]*)*))$
attr-rgx=(?:(?P<snake>[a-z_][a-z0-9_]*)|(?P<camel>[a-z]+(?:[A-Z][a-z0-9]*)*))$
argument-rgx=(?:(?P<snake>[a-z_][a-z0-9_]*)|(?P<camel>[a-z]+(?:[A-Z][a-z0-9]*)*))$
variable-rgx=(?:(?P<snake>[a-z_][a-z0-9_]*)|(?P<camel>[a-z]+(?:[A-Z][a-z0-9]*)*))$
class-attribute-rgx=(?:(?P<snake>[a-z_][a-z0-9_]*)|(?P<camel>[a-z]+(?:[A-Z][a-z0-9]*)*))$
class-const-rgx=(?:(?P<snake>[A-Z_][A-Z0-9_]*)|(?P<camel>[A-Z][a-zA-Z0-9]*))$
inlinevar-rgx=(?:(?P<snake>[a-z_][a-z0-9_]*)|(?P<camel>[a-z]+(?:[A-Z][a-z0-9]*)*))$

[design]
max-locals = 24

[MESSAGES CONTROL]
disable=W0621
disable=W0102
45 changes: 45 additions & 0 deletions examples/sphericalPlotting/plotArcs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
from typing import List

from foundationTypes.mathTypes.UnitSphericalArc import UnitSphericalArc

from pyMathToolsPlotHelpers.plotUnitSpherical import (
deg45,
deg90,
deg180,
deg22_5,
plot_unit_spherical_multiplot,
)

from pyMathTools.spherical.constructors import (
arc_from_two_points,
)
from pyMathTools.spherical.sphericalTransforms import compute_spherical_arc_endpoint


def demo() -> None:
"""Demonstration of multiplot view showing spherical small circles in three different projections."""

arc1 = UnitSphericalArc(orient=0, azimuth=0, polar=0, arc_length=deg90)
arc2 = UnitSphericalArc(orient=deg90, azimuth=0, polar=deg90, arc_length=deg90)
az, po = compute_spherical_arc_endpoint(arc2)
arc3 = arc_from_two_points(
azimuth1=az,
polar1=po,
azimuth2=arc1.azimuth,
polar2=arc1.polar,
)

arcs: List[UnitSphericalArc] = [
arc1,
arc2,
arc3,
]

_ = plot_unit_spherical_multiplot(
arcs=arcs,
show_plot=True,
)


if __name__ == "__main__":
demo()
80 changes: 80 additions & 0 deletions examples/sphericalPlotting/plotQuatUnitCircles.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
"""
Example: Visualizing Quaternion-Derived Small Circles on the Unit Sphere

This script demonstrates how to convert quaternions to spherical small circles
and visualize them using multiple projections. It serves as a validation and
walkthrough for the quaternion-to-spherical conversion and plotting utilities.

Steps:
------
1. Import required modules and functions.
2. Convert several canonical quaternions (identity and axis-aligned) to
UnitSphericalSmallCircle objects.
3. Plot these circles using the multiplot function, which shows flat projection,
polar, and 3D views.

Usage:
------
Run this script directly to see the resulting plots and validate the conversion.

Expected Output:
----------------
- The identity quaternion (`quaternion.one`) should map to the north pole.
- `quaternion.x`, `quaternion.y`, and `quaternion.z` should map to circles
centered on the X, Y, and Z axes, respectively.

"""

from typing import List
from numpy import pi

from foundationTypes.mathTypes.UnitSphericalSmallCircle import UnitSphericalSmallCircle

from pyMathTools.spatial.Quaternion import Quaternion

from pyMathToolsPlotHelpers.plotUnitSpherical import (
plot_unit_spherical_multiplot,
)


def main():
"""
Convert canonical quaternions to spherical small circles and plot them.

- quaternion.one: Identity quaternion (should map to north pole)
- quaternion.x: X-axis quaternion
- quaternion.y: Y-axis quaternion
- quaternion.z: Z-axis quaternion

All circles use a radius angle of pi/8 except y and z, which use the default.
"""

quat4 = Quaternion.from_unit_x_to_vector([1, 0, 0])
quat5 = Quaternion.from_unit_x_to_vector([0, 1, 0])
quat6 = Quaternion.from_unit_x_to_vector([0, 0, 1])

quat1 = Quaternion.from_components(0, 1, 0, 0)
quat2 = Quaternion.from_components(0, 0, 1, 0)
quat3 = Quaternion.from_components(0, 0, 0, 1)

circles: List[UnitSphericalSmallCircle] = [
quat1.to_unitSphericalSmallCircle(radius_angle=pi / 8),
quat2.to_unitSphericalSmallCircle(radius_angle=pi / 8),
quat3.to_unitSphericalSmallCircle(),
quat4.to_unitSphericalSmallCircle(radius_angle=pi / 16),
quat5.to_unitSphericalSmallCircle(radius_angle=pi / 16),
quat6.to_unitSphericalSmallCircle(radius_angle=pi / 16),
]

quats: List[Quaternion] = [quat1, quat2, quat3, quat4, quat5, quat6]

# from_vector_part
_ = plot_unit_spherical_multiplot(
circles=circles,
quaternions=quats,
show_plot=True,
)


if __name__ == "__main__":
main()
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ license = {text = "MIT"}
dependencies = [
"pyFoundationTools @ git+https://github.com/kopecn/py-foundationTools.git@dev",
"matplotlib",
"numpy-quaternion",
]

[project.optional-dependencies]
Expand Down
31 changes: 31 additions & 0 deletions src/pyMathTools/hints.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
"""
Type hinting utilities for complex mathematical operations.

This module provides reusable type hints for NumPy arrays and scalars,
enabling strict and clear typing in mathematical code throughout the package.
"""

from typing import Union, TYPE_CHECKING
import numpy as np
from numpy import float64
from numpy.typing import NDArray
import quaternion

if TYPE_CHECKING:
from pyMathTools.spatial.quaternion import Quaternion

# Basic numeric types
FloatOrNDArray = Union[float, NDArray[float64]]
FloatNDArray = NDArray[float64]

# Quaternion types
QuaternionLike = Union["Quaternion", np.quaternion, NDArray[np.quaternion]]
FloatOrQuaternion = Union["Quaternion", float, np.quaternion]
FloatArray3 = NDArray[float64] # Shape (..., 3)
FloatArray4 = NDArray[float64] # Shape (..., 4)
RotationMatrix = NDArray[float64] # Shape (..., 3, 3)


if __name__ == "__main__":
q = quaternion.one
assert isinstance(q, np.quaternion)
1 change: 0 additions & 1 deletion src/pyMathTools/pyMathTools.py

This file was deleted.

Loading