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

Fix percentage distance methods #339

Merged
merged 25 commits into from
Nov 27, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
4569d36
Corrected calculation of arc length
JackB-Ansys Jul 15, 2024
cd113d4
Corrected make percentage method use percentage not fraction
JackB-Ansys Jul 15, 2024
abfe2a3
Deprecated get_coordinate_from_percentage_distance methods. Replaced …
JackB-Ansys Jul 15, 2024
0f9f663
update tests
JackB-Ansys Jul 17, 2024
4009764
Merge remote-tracking branch 'refs/remotes/origin/main' into fix_perc…
JackB-Ansys Aug 14, 2024
6f112a0
Added deprecation warnings
JackB-Ansys Aug 14, 2024
35e19a5
Added more tests for updated get_coordinate_from_distance method (new…
JackB-Ansys Aug 14, 2024
6ab1540
Added more tests for updated get_coordinate_from_distance method (tes…
JackB-Ansys Aug 15, 2024
3343f34
Added more tests for updated get_coordinate_from_distance method (tes…
JackB-Ansys Aug 15, 2024
ffa98dc
Merge branch 'main' into fix_percentage_distance_methods
jgsdavies Aug 20, 2024
741b597
Merge branch 'main' into fix_percentage_distance_methods
jgsdavies Sep 17, 2024
da2b09d
Merge branch 'main' into fix_percentage_distance_methods
jgsdavies Oct 7, 2024
ade8649
Added test for arc with negative radius for deprecated get_coordinate…
JackB-Ansys Oct 22, 2024
a39970c
Added tests to check error is raised when no distance, percentage or …
JackB-Ansys Oct 22, 2024
7045440
Merge remote-tracking branch 'refs/remotes/origin/main' into fix_perc…
JackB-Ansys Oct 22, 2024
ab64e0f
Merge remote-tracking branch 'refs/remotes/origin/main' into fix_perc…
JackB-Ansys Oct 30, 2024
3aed80b
Merge remote-tracking branch 'refs/remotes/origin/main' into fix_perc…
JackB-Ansys Nov 4, 2024
53fec21
Merge branch 'main' into fix_percentage_distance_methods
jgsdavies Nov 12, 2024
0ffb4f0
Merge branch 'main' into fix_percentage_distance_methods
james-packer Nov 22, 2024
387299e
Update src/ansys/motorcad/core/geometry.py
JackB-Ansys Nov 26, 2024
6c19450
Update src/ansys/motorcad/core/geometry.py
JackB-Ansys Nov 26, 2024
bd63100
Update src/ansys/motorcad/core/geometry.py
JackB-Ansys Nov 26, 2024
87d9ff9
Update src/ansys/motorcad/core/geometry.py
JackB-Ansys Nov 26, 2024
b95a925
Update src/ansys/motorcad/core/geometry.py
JackB-Ansys Nov 26, 2024
c5c03fa
Merge branch 'main' into fix_percentage_distance_methods
james-packer Nov 26, 2024
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
126 changes: 72 additions & 54 deletions src/ansys/motorcad/core/geometry.py
Original file line number Diff line number Diff line change
Expand Up @@ -918,51 +918,63 @@
else:
raise Exception("Line can only be mirrored about Line()")

def get_coordinate_from_percentage_distance(self, ref_coordinate, percentage):
"""Get the coordinate at the percentage distance along the line from the reference.
def get_coordinate_from_percentage_distance(self, ref_coordinate, fraction):
"""Get the coordinate at a fractional distance along the line from the reference coord.

.. note::
JackB-Ansys marked this conversation as resolved.
Show resolved Hide resolved
This method is deprecated. Use the :func:`Arc.get_coordinate_from_distance`
JackB-Ansys marked this conversation as resolved.
Show resolved Hide resolved
method with the `fraction = ` or `percentage =` argument.

Parameters
----------
ref_coordinate : Coordinate
Entity reference coordinate.

percentage : float
Percentage distance along Line.
fraction : float
Fractional distance along Arc.
JackB-Ansys marked this conversation as resolved.
Show resolved Hide resolved

Returns
-------
Coordinate
Coordinate at percentage distance along Line.
Coordinate at fractional distance along Arc.
JackB-Ansys marked this conversation as resolved.
Show resolved Hide resolved
"""
if ref_coordinate == self.end:
coordinate_1 = self.end
coordinate_2 = self.start
else:
coordinate_1 = self.start
coordinate_2 = self.end

t = (self.length * percentage) / self.length
x = ((1 - t) * coordinate_1.x) + (t * coordinate_2.x)
y = ((1 - t) * coordinate_1.y) + (t * coordinate_2.y)
return self.get_coordinate_from_distance(ref_coordinate, fraction=fraction)

return Coordinate(x, y)

def get_coordinate_from_distance(self, ref_coordinate, distance):
def get_coordinate_from_distance(
JackB-Ansys marked this conversation as resolved.
Show resolved Hide resolved
self, ref_coordinate, distance=None, fraction=None, percentage=None
):
"""Get the coordinate at the specified distance along the line from the reference.

Parameters
----------
ref_coordinate : Coordinate
Entity reference coordinate.

distance : float
distance : float, optional
Distance along Line.

fraction : float, optional
Fractional distance along Line.

percentage : float, optional
Percentage distance along Line.

Returns
-------
Coordinate
Coordinate at distance along Line.
"""
if not distance:
if fraction:
distance = self.length * fraction
if percentage:
if percentage != fraction * 100:
print("Both fraction and percentage provided. Using fraction.")
elif percentage:
distance = self.length * (percentage / 100)

Check warning on line 974 in src/ansys/motorcad/core/geometry.py

View check run for this annotation

Codecov / codecov/patch

src/ansys/motorcad/core/geometry.py#L971-L974

Added lines #L971 - L974 were not covered by tests
else:
raise Exception("You must provide either a distance, fraction or percentage.")

Check warning on line 976 in src/ansys/motorcad/core/geometry.py

View check run for this annotation

Codecov / codecov/patch

src/ansys/motorcad/core/geometry.py#L976

Added line #L976 was not covered by tests

if ref_coordinate == self.end:
coordinate_1 = self.end
coordinate_2 = self.start
Expand Down Expand Up @@ -1082,56 +1094,74 @@
x_shift, y_shift = rt_to_xy(abs(self.radius), angle)
return Coordinate(self.centre.x + x_shift, self.centre.y + y_shift)

def get_coordinate_from_percentage_distance(self, ref_coordinate, percentage):
"""Get the coordinate at the percentage distance along the arc from the reference coord.
def get_coordinate_from_percentage_distance(self, ref_coordinate, fraction):
"""Get the coordinate at a fractional distance along the arc from the reference coord.

.. note::
This method is deprecated. Use the :func:`Arc.get_coordinate_from_distance`
method with the `fraction = ` or `percentage =` argument.

Parameters
----------
ref_coordinate : Coordinate
Entity reference coordinate.

percentage : float
Percentage distance along Arc.
fraction : float
Fractional distance along Arc.

Returns
-------
Coordinate
Coordinate at percentage distance along Arc.
Coordinate at fractional distance along Arc.
"""
length = self.length * percentage

return self.get_coordinate_from_distance(ref_coordinate, length)
return self.get_coordinate_from_distance(ref_coordinate, fraction=fraction)

def get_coordinate_from_distance(self, ref_coordinate, distance):
def get_coordinate_from_distance(
self, ref_coordinate, distance=None, fraction=None, percentage=None
):
"""Get the coordinate at the specified distance along the arc from the reference coordinate.

Parameters
----------
ref_coordinate : Coordinate
Entity reference coordinate.

distance : float
distance : float, optional
Distance along arc.

fraction : float, optional
Fractional distance along Line.
JackB-Ansys marked this conversation as resolved.
Show resolved Hide resolved

percentage : float, optional
Percentage distance along Line.
JackB-Ansys marked this conversation as resolved.
Show resolved Hide resolved

Returns
-------
Coordinate
Coordinate at distance along Arc.
"""
if ref_coordinate == self.end:
if self.radius >= 0:
# anticlockwise
angle = atan2(ref_coordinate.y, ref_coordinate.x) - (distance / self.radius)
if not distance:
if fraction:
distance = self.length * fraction
if percentage:
if percentage != fraction * 100:
print("Both fraction and percentage provided. Using fraction.")

Check warning on line 1148 in src/ansys/motorcad/core/geometry.py

View check run for this annotation

Codecov / codecov/patch

src/ansys/motorcad/core/geometry.py#L1147-L1148

Added lines #L1147 - L1148 were not covered by tests
elif percentage:
distance = self.length * (percentage / 100)
else:
angle = atan2(ref_coordinate.y, ref_coordinate.x) + (distance / self.radius)
else:
if self.radius >= 0:
# anticlockwise
angle = atan2(ref_coordinate.y, ref_coordinate.x) + (distance / self.radius)
else:
angle = atan2(ref_coordinate.y, ref_coordinate.x) - (distance / self.radius)
raise Exception("You must provide either a distance, fraction or percentage.")

Check warning on line 1152 in src/ansys/motorcad/core/geometry.py

View check run for this annotation

Codecov / codecov/patch

src/ansys/motorcad/core/geometry.py#L1152

Added line #L1152 was not covered by tests

return self.centre + Coordinate(*rt_to_xy(self.radius, degrees(angle)))
ref_coordinate_angle = atan2(
(ref_coordinate.y - self.centre.y), (ref_coordinate.x - self.centre.x)
)
if ref_coordinate == self.end:
e = -1
else:
e = 1
angle = ref_coordinate_angle + e * (
distance / self.radius
) # sign of the radius accounts for clockwise/anticlockwise arcs
return self.centre + Coordinate(*rt_to_xy(abs(self.radius), degrees(angle)))

def mirror(self, mirror_line):
"""Mirror arc about a line.
Expand Down Expand Up @@ -1164,19 +1194,7 @@
float
Length of arc
"""
radius, angle_1 = xy_to_rt(self.start.x, self.start.y)
radius, angle_2 = xy_to_rt(self.end.x, self.end.y)

if self.radius == 0:
arc_angle = 0
elif ((self.radius > 0) and (angle_1 > angle_2)) or (
(self.radius < 0) and angle_2 < angle_1
):
arc_angle = angle_2 - (angle_1 - 360)
else:
arc_angle = angle_2 - angle_1

return self.radius * radians(arc_angle)
return abs(self.radius * radians(self.total_angle))

def reverse(self):
"""Reverse Arc entity."""
Expand Down
53 changes: 49 additions & 4 deletions tests/test_geometry.py
Original file line number Diff line number Diff line change
Expand Up @@ -531,14 +531,31 @@ def test_line_length():
assert line.length == sqrt(2)


def test_arc_get_coordinate_from_percentage_distance():
def test_arc_get_coordinate_from_fractional_distance():
JackB-Ansys marked this conversation as resolved.
Show resolved Hide resolved
arc = geometry.Arc(
geometry.Coordinate(-1, 0), geometry.Coordinate(1, 0), geometry.Coordinate(0, 0), 1
)

coord = arc.get_coordinate_from_percentage_distance(geometry.Coordinate(-1, 0), 0.5)
assert isclose(coord.x, 0, abs_tol=1e-12)
assert isclose(coord.y, -1, abs_tol=1e-12)
coord_1 = arc.get_coordinate_from_percentage_distance(geometry.Coordinate(-1, 0), 0.5)
assert isclose(coord_1.x, 0, abs_tol=1e-12)
assert isclose(coord_1.y, -1, abs_tol=1e-12)

# test an arc that failed with the old definition of get_coordinate_from_percentage_distance()
arc_2 = geometry.Arc(geometry.Coordinate(62, 20), geometry.Coordinate(56, 33), radius=45)
coord_2 = arc_2.get_coordinate_from_percentage_distance(arc_2.end, 1e-13)
assert math.isclose(arc_2.end.x, coord_2.x, abs_tol=1e-12)
assert math.isclose(arc_2.end.y, coord_2.y, abs_tol=1e-12)
coord_3 = arc_2.get_coordinate_from_percentage_distance(arc_2.start, 1e-13)
assert math.isclose(arc_2.start.x, coord_3.x, abs_tol=1e-12)
assert math.isclose(arc_2.start.y, coord_3.y, abs_tol=1e-12)
# test arc drawn clockwise
arc_4 = geometry.Arc(geometry.Coordinate(56, 33), geometry.Coordinate(62, 20), radius=45)
coord_4 = arc_4.get_coordinate_from_distance(arc_4.end, 1e-13)
assert math.isclose(arc_4.end.x, coord_4.x, abs_tol=1e-12)
assert math.isclose(arc_4.end.y, coord_4.y, abs_tol=1e-12)
coord_5 = arc_4.get_coordinate_from_distance(arc_4.start, 1e-13)
assert math.isclose(arc_4.start.x, coord_5.x, abs_tol=1e-12)
assert math.isclose(arc_4.start.y, coord_5.y, abs_tol=1e-12)


def test_arc_get_coordinate_from_distance():
Expand All @@ -550,6 +567,34 @@ def test_arc_get_coordinate_from_distance():
assert math.isclose(coord.x, 0, abs_tol=1e-12)
assert math.isclose(coord.y, -1, abs_tol=1e-12)

# test an arc that failed with the old definition of get_coordinate_from_distance()
arc_2 = geometry.Arc(geometry.Coordinate(62, 20), geometry.Coordinate(56, 33), radius=45)
coord_2 = arc_2.get_coordinate_from_distance(arc_2.end, 1e-15)
assert math.isclose(arc_2.end.x, coord_2.x, abs_tol=1e-12)
assert math.isclose(arc_2.end.y, coord_2.y, abs_tol=1e-12)
coord_3 = arc_2.get_coordinate_from_distance(arc_2.start, 1e-15)
assert math.isclose(arc_2.start.x, coord_3.x, abs_tol=1e-12)
assert math.isclose(arc_2.start.y, coord_3.y, abs_tol=1e-12)
# test arc drawn clockwise
arc_4 = geometry.Arc(geometry.Coordinate(56, 33), geometry.Coordinate(62, 20), radius=45)
coord_4 = arc_4.get_coordinate_from_distance(arc_4.end, 1e-15)
assert math.isclose(arc_4.end.x, coord_4.x, abs_tol=1e-12)
assert math.isclose(arc_4.end.y, coord_4.y, abs_tol=1e-12)
coord_5 = arc_4.get_coordinate_from_distance(arc_4.start, 1e-15)
assert math.isclose(arc_4.start.x, coord_5.x, abs_tol=1e-12)
assert math.isclose(arc_4.start.y, coord_5.y, abs_tol=1e-12)
coord_6 = arc_2.get_coordinate_from_distance(arc_2.start, 5)
assert math.isclose(60.389142028418, coord_6.x, abs_tol=1e-12)
assert math.isclose(24.730689908764, coord_6.y, abs_tol=1e-12)

coord_7 = arc.get_coordinate_from_distance(geometry.Coordinate(-1, 0), fraction=0.5)
assert isclose(coord_7.x, 0, abs_tol=1e-12)
assert isclose(coord_7.y, -1, abs_tol=1e-12)

coord_8 = arc.get_coordinate_from_distance(geometry.Coordinate(-1, 0), percentage=50)
assert isclose(coord_8.x, 0, abs_tol=1e-12)
assert isclose(coord_8.y, -1, abs_tol=1e-12)


def test_arc_length():
arc = geometry.Arc(
Expand Down
Loading