Skip to content

Commit

Permalink
New sub-packages: geometry, visualiser, linkage.
Browse files Browse the repository at this point in the history
Removes sub-package: interface.
It it roughly a big code reorganization.
  • Loading branch information
HugoFara committed Oct 1, 2024
2 parents 3607006 + 0faeeee commit c018ee7
Show file tree
Hide file tree
Showing 21 changed files with 329 additions and 288 deletions.
14 changes: 7 additions & 7 deletions pylinkage/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,15 @@
circle_intersect,
intersection
)
from .interface import (
from .exceptions import (
UnbuildableError,
HypostaticError,
NotCompletelyDefinedError,
Pivot,
)
from .linkage import (
Linkage,
kinematic_default_test,
bounding_box,
)
from .joints import (
Crank,
Expand All @@ -34,16 +37,13 @@
Revolute,
Static,
)
from .joints.revolute import Pivot
from .optimization import (
generate_bounds,
trials_and_errors_optimization,
particle_swarm_optimization
)
from .utility import (
kinematic_default_test,
particle_swarm_optimization,
kinematic_maximization,
kinematic_minimization,
bounding_box
)
from .visualizer import (
plot_static_linkage,
Expand Down
3 changes: 3 additions & 0 deletions pylinkage/collections/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
"""
Package for collection objects.
"""
from .agent import Agent
from .mutable_agent import MutableAgent
File renamed without changes.
16 changes: 16 additions & 0 deletions pylinkage/geometry/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
"""
Basic geometry package.
"""

from .core import (
dist,
sqr_dist,
norm,
cyl_to_cart,
)
from .secants import (
circle_intersect,
circle_line_intersection,
circle_line_from_points_intersection,
intersection,
)
101 changes: 101 additions & 0 deletions pylinkage/geometry/core.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
"""
Basic geometry features.
"""
import sys
import warnings
import math


def dist_builtin(point1, point2):
"""Euclidian distance between two 2D points.
Legacy built-in unoptimized equivalent of `math.dist` in Python 3.8.
:param tuple[float, float] point1: First point
:param tuple[float, float] point2: Second point
"""
return math.sqrt(
(point1[0] - point2[0]) ** 2 + (point1[1] - point2[1]) ** 2
)


if sys.version_info >= (3, 8, 0):
dist = math.dist
else:
warnings.warn('Unable to import dist from math. Using built-in function.')
dist = dist_builtin


def sqr_dist(point1, point2):
"""
Square of the distance between two points.
Faster than dist.
:param tuple[float, float] point1: First point to compare
:param tuple[float, float] point2: Second point
:return float: Computed distance
"""
return (point1[0] - point2[0]) ** 2 + (point1[1] - point2[1]) ** 2


def get_nearest_point(reference_point, first_point, second_point):
"""
Return the point closer to the reference.
:param tuple[float, float] reference_point: Point to compare to
:param tuple[float, float] first_point: First point candidate
:param tuple[float, float] second_point: Second point candidate
:return tuple[float, float]: Either first point or second point
"""
if reference_point == first_point or reference_point == second_point:
return reference_point
if sqr_dist(reference_point, first_point) < sqr_dist(reference_point, second_point):
return first_point
return second_point


def norm(vec):
"""
Return the norm of a 2-dimensional vector.
:param tuple[float, float] vec: Vector to get norm from
"""
return math.sqrt(vec[0] ** 2 + vec[1] ** 2)


def cyl_to_cart(radius, theta, ori=(0, 0)):
"""Convert polar coordinates into cartesian.
:param radius: distance from ori
:param theta: angle is the angle starting from abscissa axis
:param ori: origin point (Default value = (0)).
"""
return radius * math.cos(theta) + ori[0], radius * math.sin(theta) + ori[1]


def line_from_points(first_point, second_point):
"""
A cartesian equation of the line joining two points.
:param tuple[float, float] first_point: One point of the line.
:param tuple[float, float] second_point: Another point on the line.
:return tuple[float, float, float]: A cartesian equation of this line.
"""
if first_point == second_point:
warnings.warn("Cannot choose a line, inputs points are the same!")
return 0, 0, 0
director = (
second_point[0] - first_point[0],
second_point[1] - first_point[1]
)
# The barycenter should give more precision
mean = (
(first_point[0] + second_point[0]) / 2,
(first_point[1] + second_point[1]) / 2
)
equilibrium = mean[0] * director[1] - mean[1] * director[0]
return -director[1], director[0], equilibrium
101 changes: 3 additions & 98 deletions pylinkage/geometry.py → pylinkage/geometry/secants.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,84 +10,13 @@
@author: HugoFara
"""
import math
import warnings


def dist_builtin(point1, point2):
"""Euclidian distance between two 2D points.
Legacy built-in unoptimized equivalent of math.dist in Python 3.8.
:param point1:
:param point2:
"""
return math.sqrt(
(point1[0] - point2[0]) ** 2 + (point1[1] - point2[1]) ** 2
)


if hasattr(math, 'dist'):
dist = math.dist
else:
print('Unable to import dist from math. Using built-in function.')
dist = dist_builtin


def sqr_dist(point1, point2):
"""
Square of the distance between two points.
Faster than dist.
:param tuple[float, float] point1: First point to compare
:param tuple[float, float] point2: Second point
:return float: Computed distance
"""
return (point1[0] - point2[0]) ** 2 + (point1[1] - point2[1]) ** 2


def get_nearest_point(reference_point, first_point, second_point):
"""
Return the point closer to the reference.
:param tuple[float, float] reference_point: Point to compare to
:param tuple[float, float] first_point: First point candidate
:param tuple[float, float] second_point: Second point candidate
:return tuple[float, float]: Either first point or second point
"""
if reference_point == first_point or reference_point == second_point:
return reference_point
if sqr_dist(reference_point, first_point) < sqr_dist(reference_point, second_point):
return first_point
return second_point


def norm(vec):
"""
Return the norm of a 2-dimensional vector.
:param vec:
"""
return math.sqrt(vec[0] ** 2 + vec[1] ** 2)


def cyl_to_cart(radius, theta, ori=(0, 0)):
"""Convert polar coordinates into cartesian.
:param radius: distance from ori
:param theta: angle is the angle starting from abscissa axis
:param ori: origin point (Default value = (0)).
"""
return radius * math.cos(theta) + ori[0], radius * math.sin(theta) + ori[1]
from .core import dist


def secant_circles_intersections(
distance, dist_x, dist_y, mid_dist, radius1, projected
):
distance, dist_x, dist_y, mid_dist, radius1, projected
):
"""Return the TWO intersections of secant circles."""
# Distance between projected P and points
# and the points of which P is projection
Expand Down Expand Up @@ -166,30 +95,6 @@ def circle_intersect(circle1, circle2, tol=0.0):
return 1, projected


def line_from_points(first_point, second_point):
"""
A cartesian equation of the line joining two points.
:param tuple[float, float] first_point: One point of the line.
:param tuple[float, float] second_point: Another point on the line.
:return tuple[float, float, float]: A cartesian equation of this line.
"""
if first_point == second_point:
warnings.warn("Cannot choose a line, inputs points are the same!")
return 0, 0, 0
director = (
second_point[0] - first_point[0],
second_point[1] - first_point[1]
)
# The barycenter should give more precision
mean = (
(first_point[0] + second_point[0]) / 2,
(first_point[1] + second_point[1]) / 2
)
equilibrium = mean[0] * director[1] - mean[1] * director[0]
return -director[1], director[0], equilibrium


def circle_line_from_points_intersection(circle, first_point, second_point):
"""
Intersection(s) of a circle and a line defined by two points.
Expand Down
18 changes: 0 additions & 18 deletions pylinkage/interface/__init__.py

This file was deleted.

2 changes: 1 addition & 1 deletion pylinkage/joints/crank.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

from . import joint as pl_joint
from .. import geometry as pl_geom
from ..interface import exceptions as pl_exceptions
from .. import exceptions as pl_exceptions


class Crank(pl_joint.Joint):
Expand Down
2 changes: 1 addition & 1 deletion pylinkage/joints/fixed.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import math

from .. import geometry as pl_geom
from ..interface import exceptions as pl_exceptions
from .. import exceptions as pl_exceptions
from . import joint as pl_joint


Expand Down
2 changes: 1 addition & 1 deletion pylinkage/joints/linear.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
Definition of a linear joint.
"""
from . import joint as pl_joint
from ..interface import exceptions as pl_exceptions
from .. import exceptions as pl_exceptions
from .. import geometry as geom


Expand Down
6 changes: 4 additions & 2 deletions pylinkage/joints/revolute.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from math import atan2

from .. import geometry as pl_geom
from ..interface import exceptions as pl_exceptions
from .. import exceptions as pl_exceptions
from . import joint as pl_joint


Expand Down Expand Up @@ -113,7 +113,9 @@ def reload(self):
if intersections[0] == 1:
self.x, self.y = intersections[1]
elif intersections[0] == 2:
self.x, self.y = pl_geom.get_nearest_point(self.coord(), intersections[1], intersections[2])
self.x, self.y = pl_geom.core.get_nearest_point(
self.coord(), intersections[1], intersections[2]
)
elif intersections[0] == 3:
warnings.warn(
f"Joint {self.name} has an infinite number of"
Expand Down
8 changes: 8 additions & 0 deletions pylinkage/linkage/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
"""
Definition and analysis of a linkage as a dynamic set of joints.
"""
from .linkage import Linkage
from .analysis import (
kinematic_default_test,
bounding_box,
)
Loading

0 comments on commit c018ee7

Please sign in to comment.