Skip to content

Commit

Permalink
Merge pull request #22131 from smichr/geom-evalf
Browse files Browse the repository at this point in the history
all geometry entities have evalf capability
  • Loading branch information
smichr authored Sep 21, 2021
2 parents 1303710 + 64d5414 commit 9dd704b
Show file tree
Hide file tree
Showing 7 changed files with 61 additions and 7 deletions.
8 changes: 8 additions & 0 deletions sympy/geometry/curve.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from sympy.core import sympify, diff
from sympy.core.compatibility import is_sequence
from sympy.core.containers import Tuple
from sympy.core.evalf import prec_to_dps
from sympy.core.symbol import _symbol
from sympy.geometry.entity import GeometryEntity, GeometrySet
from sympy.geometry.point import Point
Expand Down Expand Up @@ -89,6 +90,13 @@ def _eval_subs(self, old, new):
if old == self.parameter:
return Point(*[f.subs(old, new) for f in self.functions])

def _eval_evalf(self, prec=15, **options):
f, (t, a, b) = self.args
dps = prec_to_dps(prec)
f = tuple([i.evalf(n=dps, **options) for i in f])
a, b = [i.evalf(n=dps, **options) for i in (a, b)]
return self.func(f, (t, a, b))

def arbitrary_point(self, parameter='t'):
"""A parameterized point on the curve.
Expand Down
8 changes: 8 additions & 0 deletions sympy/geometry/ellipse.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

from sympy import Expr, Eq
from sympy.core import S, pi, sympify
from sympy.core.evalf import prec_to_dps
from sympy.core.parameters import global_parameters
from sympy.core.logic import fuzzy_bool
from sympy.core.numbers import Rational, oo
Expand Down Expand Up @@ -1604,6 +1605,13 @@ def __new__(cls, *args, **kwargs):

raise GeometryError("Circle.__new__ received unknown arguments")

def _eval_evalf(self, prec=15, **options):
pt, r = self.args
dps = prec_to_dps(prec)
pt = pt.evalf(n=dps, **options)
r = r.evalf(n=dps, **options)
return self.func(pt, r, evaluate=False)

@property
def circumference(self):
"""The circumference of the circle.
Expand Down
3 changes: 2 additions & 1 deletion sympy/geometry/entity.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
from sympy.core.basic import Basic
from sympy.core.compatibility import is_sequence
from sympy.core.containers import Tuple
from sympy.core.evalf import EvalfMixin
from sympy.core.sympify import sympify
from sympy.functions import cos, sin
from sympy.matrices import eye
Expand Down Expand Up @@ -58,7 +59,7 @@
]


class GeometryEntity(Basic):
class GeometryEntity(Basic, EvalfMixin):
"""The base class for all geometrical entities.
This class doesn't represent any particular geometric entity, it only
Expand Down
11 changes: 10 additions & 1 deletion sympy/geometry/plane.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

from sympy import simplify # type:ignore
from sympy.core import Dummy, Rational, S, Symbol
from sympy.core.evalf import prec_to_dps
from sympy.core.symbol import _symbol
from sympy.core.compatibility import is_sequence
from sympy.functions.elementary.trigonometric import cos, sin, acos, asin, sqrt
Expand Down Expand Up @@ -60,8 +61,9 @@ def __new__(cls, p1, a=None, b=None, **kwargs):
normal_vector = tuple(Matrix(a).cross(Matrix(b)))
else:
a = kwargs.pop('normal_vector', a)
evaluate = kwargs.get('evaluate', True)
if is_sequence(a) and len(a) == 3:
normal_vector = Point3D(a).args
normal_vector = Point3D(a).args if evaluate else a
else:
raise ValueError(filldedent('''
Either provide 3 3D points or a point with a
Expand All @@ -86,6 +88,13 @@ def __contains__(self, o):
except TypeError:
return False

def _eval_evalf(self, prec=15, **options):
pt, tup = self.args
dps = prec_to_dps(prec)
pt = pt.evalf(n=dps, **options)
tup = tuple([i.evalf(n=dps, **options) for i in tup])
return self.func(pt, normal_vector=tup, evaluate=False)

def angle_between(self, o):
"""Angle between the plane and other geometric entity.
Expand Down
6 changes: 3 additions & 3 deletions sympy/geometry/point.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
from sympy.core.numbers import Float
from sympy.core.parameters import global_parameters
from sympy.core.add import Add
from sympy.core.evalf import prec_to_dps
from sympy.utilities.iterables import uniq
from sympy.utilities.misc import filldedent, func_name, Undecidable

Expand Down Expand Up @@ -446,7 +447,7 @@ def equals(self, other):
return False
return all(a.equals(b) for a, b in zip(self, other))

def evalf(self, prec=None, **options):
def _eval_evalf(self, prec=15, **options):
"""Evaluate the coordinates of the point.
This method will, where possible, create and return a new Point
Expand Down Expand Up @@ -474,7 +475,7 @@ def evalf(self, prec=None, **options):
Point2D(0.5, 1.5)
"""
coords = [x.evalf(prec, **options) for x in self.args]
coords = [x.evalf(n=prec_to_dps(prec), **options) for x in self.args]
return Point(*coords, evaluate=False)

def intersection(self, other):
Expand Down Expand Up @@ -852,7 +853,6 @@ def unit(self):
and a distance of 1 from the origin"""
return self / abs(self)

n = evalf

class Point2D(Point):
"""A point in a 2-dimensional Euclidean space.
Expand Down
7 changes: 7 additions & 0 deletions sympy/geometry/polygon.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from sympy.core import Expr, S, Symbol, oo, pi, sympify
from sympy.core.compatibility import as_int, ordered
from sympy.core.evalf import prec_to_dps
from sympy.core.symbol import _symbol, Dummy, symbols
from sympy.functions.elementary.complexes import sign
from sympy.functions.elementary.piecewise import Piecewise
Expand Down Expand Up @@ -1486,6 +1487,12 @@ def __new__(self, c, r, n, rot=0, **kwargs):
obj._rot = rot % (2*S.Pi/n) if rot.is_number else rot
return obj

def _eval_evalf(self, prec=15, **options):
c, r, n, a = self.args
dps = prec_to_dps(prec)
c, r, a = [i.evalf(n=dps, **options) for i in (c, r, a)]
return self.func(c, r, n, a)

@property
def args(self):
"""
Expand Down
25 changes: 23 additions & 2 deletions sympy/geometry/tests/test_entity.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from sympy import Symbol, Rational, S
from sympy.geometry import Circle, Ellipse, Line, Point, Polygon, Ray, RegularPolygon, Segment, Triangle
from sympy import Symbol, Rational, S, pi
from sympy.geometry import (Circle, Ellipse, Point, Line, Parabola,
Polygon, Ray, RegularPolygon, Segment, Triangle, Plane, Curve)
from sympy.geometry.entity import scale, GeometryEntity
from sympy.testing.pytest import raises

Expand Down Expand Up @@ -95,3 +96,23 @@ def test_reflect_entity_overrides():
break
assert not rvert
assert pent.area.equals(-rpent.area)


def test_geometry_EvalfMixin():
x = pi
t = Symbol('t')
for g in [
Point(x, x),
Plane(Point(0, x, 0), (0, 0, x)),
Curve((x*t, x), (t, 0, x)),
Ellipse((x, x), x, -x),
Circle((x, x), x),
Line((0, x), (x, 0)),
Segment((0, x), (x, 0)),
Ray((0, x), (x, 0)),
Parabola((0, x), Line((-x, 0), (x, 0))),
Polygon((0, 0), (0, x), (x, 0), (x, x)),
RegularPolygon((0, x), x, 4, x),
Triangle((0, 0), (x, 0), (x, x)),
]:
assert str(g).replace('pi', '3.1') == str(g.n(2))

0 comments on commit 9dd704b

Please sign in to comment.