From 96b3f39d1df31292447c4d6218f9494e33e1566c Mon Sep 17 00:00:00 2001 From: Faisal Riyaz Date: Fri, 26 Jun 2020 20:39:43 +0530 Subject: [PATCH 1/6] Add method to convert some Gemoetric Entities to a ParametricRegion vector_integrate function was modified to integrate --- sympy/geometry/curve.py | 7 +++++++ sympy/geometry/ellipse.py | 8 ++++++++ sympy/geometry/line.py | 22 ++++++++++++++++++++++ sympy/geometry/point.py | 4 ++++ sympy/vector/integrals.py | 22 ++++++++++++++++++++-- 5 files changed, 61 insertions(+), 2 deletions(-) diff --git a/sympy/geometry/curve.py b/sympy/geometry/curve.py index 5f939a33249a..54f489310823 100644 --- a/sympy/geometry/curve.py +++ b/sympy/geometry/curve.py @@ -145,6 +145,13 @@ def arbitrary_point(self, parameter='t'): 'and cannot be used as a parameter.' % tnew.name) return Point(*[w.subs(t, tnew) for w in self.functions]) + def parametric_region(self): + from sympy.vector import ParametricRegion + + definition = self.arbitrary_point(self.parameter).args + bounds = self.limits + return ParametricRegion(definition, bounds) + @property def free_symbols(self): """Return a set of symbols other than the bound symbols used to diff --git a/sympy/geometry/ellipse.py b/sympy/geometry/ellipse.py index b16a805a50ed..9c76cfe70f6c 100644 --- a/sympy/geometry/ellipse.py +++ b/sympy/geometry/ellipse.py @@ -247,6 +247,14 @@ def arbitrary_point(self, parameter='t'): return Point(self.center.x + self.hradius*cos(t), self.center.y + self.vradius*sin(t)) + def parametric_region(self, parameter='t'): + from sympy.vector import ParametricRegion + + definition = self.arbitrary_point(parameter).args + t = _symbol(parameter, real=True) + bounds = (t, 0, 2*pi) + return ParametricRegion(definition, bounds) + @property def area(self): """The area of the ellipse. diff --git a/sympy/geometry/line.py b/sympy/geometry/line.py index 33805b37e757..0600c07d4b6a 100644 --- a/sympy/geometry/line.py +++ b/sympy/geometry/line.py @@ -33,6 +33,7 @@ from sympy.matrices import Matrix from sympy.sets import Intersection from sympy.simplify.simplify import simplify +from sympy.solvers import solve from sympy.solvers.solveset import linear_coeffs from sympy.utilities.exceptions import SymPyDeprecationWarning from sympy.utilities.misc import Undecidable, filldedent @@ -1810,6 +1811,27 @@ def perpendicular_bisector(self, p=None): return Segment(p2, self.midpoint) return l + def _parametric_bounds(self, parameter='t'): + t = _symbol(parameter, real=True) + definition = self.arbitrary_point().args + + for i in range(0, 3): + lower_bound = solve(definition[i] - self.points[0].args[i], t) + upper_bound = solve(definition[i] - self.points[1].args[i], t) + + if len(lower_bound) == 1 and len(upper_bound) == 1: + return t, lower_bound[0], upper_bound[0] + + def parametric_region(self, parameter='t'): + """ + Returns an object of ParamRegion class representing the Segment. + """ + from sympy.vector import ParametricRegion + + definition_tuple = self.arbitrary_point(parameter).args + bounds = self._parametric_bounds() + return ParametricRegion(definition_tuple, bounds) + def plot_interval(self, parameter='t'): """The plot interval for the default geometric plot of the Segment gives values that will produce the full segment in a plot. diff --git a/sympy/geometry/point.py b/sympy/geometry/point.py index a8e79b277792..fda293cbf596 100644 --- a/sympy/geometry/point.py +++ b/sympy/geometry/point.py @@ -612,6 +612,10 @@ def is_concyclic(self, *args): return True return False + def parametric_region(self): + from sympy.vector import ParametricRegion + return ParametricRegion(self.args) + @property def is_nonzero(self): """True if any coordinate is nonzero, False if every coordinate is zero, diff --git a/sympy/vector/integrals.py b/sympy/vector/integrals.py index cbc256b2ad12..8795907852e5 100644 --- a/sympy/vector/integrals.py +++ b/sympy/vector/integrals.py @@ -6,6 +6,8 @@ from sympy.integrals import Integral, integrate from sympy.core.function import diff from sympy.utilities.iterables import topological_sort, default_sort_key +from sympy.geometry.entity import GeometryEntity +from sympy.geometry import Polygon class ParametricIntegral(Basic): """ @@ -152,8 +154,24 @@ def vector_integrate(field, *region): >>> vector_integrate(C.x**2*C.z, C.x) C.x**3*C.z/3 + """ if len(region) == 1: - if isinstance(region[0], ParametricRegion): - return ParametricIntegral(field, region[0]) + region = region[0] + if isinstance(region, ParametricRegion): + return ParametricIntegral(field, region) + + if isinstance(region, GeometryEntity): + if isinstance(region, Polygon): + result = 0 + for s in region.sides: + result += vector_integrate(field, s) + return result + + try: + region = region.parametric_region() + return ParametricIntegral(field, region) + except AttributeError: + raise ValueError("SymPy cannot determine parametric representation of the region.") + return integrate(field, *region) From 80a5cbd55928e25dc744155a9d2fce15e0a9abc2 Mon Sep 17 00:00:00 2001 From: Faisal Riyaz Date: Sat, 27 Jun 2020 00:11:31 +0530 Subject: [PATCH 2/6] Added tests for vector_integrate --- sympy/geometry/curve.py | 13 +++++++++ sympy/geometry/ellipse.py | 12 ++++++++ sympy/geometry/line.py | 9 ++++++ sympy/geometry/point.py | 12 ++++++++ sympy/geometry/tests/test_line.py | 10 +++++++ sympy/vector/integrals.py | 24 +++++++++++----- sympy/vector/tests/test_integrals.py | 42 +++++++++++++++++++++++++--- 7 files changed, 111 insertions(+), 11 deletions(-) diff --git a/sympy/geometry/curve.py b/sympy/geometry/curve.py index 54f489310823..4bad3d8540bd 100644 --- a/sympy/geometry/curve.py +++ b/sympy/geometry/curve.py @@ -146,6 +146,19 @@ def arbitrary_point(self, parameter='t'): return Point(*[w.subs(t, tnew) for w in self.functions]) def parametric_region(self): + """ + Returns an object of ParamRegion class representing the Curve. + + Examples + ======== + + >>> from sympy.abc import t + >>> from sympy import Curve + >>> c = Curve((t**3, 4*t), (t, -3, 4)) + >>> c.parametric_region() + ParametricRegion((t**3, 4*t), (t, -3, 4)) + + """ from sympy.vector import ParametricRegion definition = self.arbitrary_point(self.parameter).args diff --git a/sympy/geometry/ellipse.py b/sympy/geometry/ellipse.py index 9c76cfe70f6c..ace8437acf40 100644 --- a/sympy/geometry/ellipse.py +++ b/sympy/geometry/ellipse.py @@ -248,6 +248,18 @@ def arbitrary_point(self, parameter='t'): self.center.y + self.vradius*sin(t)) def parametric_region(self, parameter='t'): + """ + Returns an object of ParamRegion class representing the Ellipse. + + Examples + ======== + + >>> from sympy import Point, Ellipse + >>> e = Ellipse(Point(1, 3), 2, 3) + >>> e.parametric_region() + ParametricRegion((2*cos(t) + 1, 3*sin(t) + 3), (t, 0, 2*pi)) + + """ from sympy.vector import ParametricRegion definition = self.arbitrary_point(parameter).args diff --git a/sympy/geometry/line.py b/sympy/geometry/line.py index 0600c07d4b6a..18dc35de3caa 100644 --- a/sympy/geometry/line.py +++ b/sympy/geometry/line.py @@ -1825,6 +1825,15 @@ def _parametric_bounds(self, parameter='t'): def parametric_region(self, parameter='t'): """ Returns an object of ParamRegion class representing the Segment. + + Examples + ======== + + >>> from sympy import Point, Segment + >>> s = Segment(Point(1, 3), Point(2, 6)) + >>> s.parametric_region() + ParametricRegion((t + 1, 3*t + 3), (t, 0, 1)) + """ from sympy.vector import ParametricRegion diff --git a/sympy/geometry/point.py b/sympy/geometry/point.py index fda293cbf596..85e20e86f947 100644 --- a/sympy/geometry/point.py +++ b/sympy/geometry/point.py @@ -613,6 +613,18 @@ def is_concyclic(self, *args): return False def parametric_region(self): + """ + Returns an object of ParamRegion class representing the Point. + + Examples + ======== + + >>> from sympy import Point + >>> p = Point(2, 5) + >>> p.parametric_region() + ParametricRegion((2, 5)) + + """ from sympy.vector import ParametricRegion return ParametricRegion(self.args) diff --git a/sympy/geometry/tests/test_line.py b/sympy/geometry/tests/test_line.py index 89af9cfc844d..565b6e035fbf 100644 --- a/sympy/geometry/tests/test_line.py +++ b/sympy/geometry/tests/test_line.py @@ -6,6 +6,7 @@ Point2D, Line2D) from sympy.geometry.line import Undecidable from sympy.geometry.polygon import _asa as asa +from sympy.vector import ParametricRegion from sympy.utilities.iterables import cartes from sympy.testing.pytest import raises, warns @@ -96,6 +97,15 @@ def test_arbitrary_point(): raises(ValueError, (lambda: Line((x, 1), (2, 3)).arbitrary_point(x))) +def test_parametric_region(): + s1 = Segment(Point(0, 0), (1, 0)) + assert s1.parametric_region() == ParametricRegion((t, 0), (t, 0, 1)) + s2 = Segment(Point(1, 2, 3), Point(1, 2, 5)) + assert s2.parametric_region() == ParametricRegion((1, 2, 2*t + 3), (t, 0, 1)) + s3 = Segment(Point(12, 56), Point(12, 56)) + assert s3.parametric_region() == ParametricRegion((12, 56)) + + def test_are_concurrent_2d(): l1 = Line(Point(0, 0), Point(1, 1)) l2 = Line(Point(x1, x1), Point(x1, 1 + x1)) diff --git a/sympy/vector/integrals.py b/sympy/vector/integrals.py index 8795907852e5..88ee2e4c855b 100644 --- a/sympy/vector/integrals.py +++ b/sympy/vector/integrals.py @@ -152,24 +152,34 @@ def vector_integrate(field, *region): >>> vector_integrate(C.x*C.i, region) 12 + Integrals over special regions can also be calculated using geometry module. + >>> from sympy.geometry import Point, Circle, Triangle + >>> c = Circle(Point(0, 2), 5) + >>> vector_integrate(C.x**2 + C.y**2, c) + 290*pi + >>> triangle = Triangle(Point(-2, 3), Point(2, 3), Point(0, 5)) + >>> vector_integrate(3*C.x**2*C.y*C.i + C.j, triangle) + -8 + + >>> vector_integrate(12*C.y**3, (C.y, 1, 3)) + 240 >>> vector_integrate(C.x**2*C.z, C.x) C.x**3*C.z/3 """ if len(region) == 1: - region = region[0] - if isinstance(region, ParametricRegion): - return ParametricIntegral(field, region) + if isinstance(region[0], ParametricRegion): + return ParametricIntegral(field, region[0]) - if isinstance(region, GeometryEntity): - if isinstance(region, Polygon): + if isinstance(region[0], GeometryEntity): + if isinstance(region[0], Polygon): result = 0 - for s in region.sides: + for s in region[0].sides: result += vector_integrate(field, s) return result try: - region = region.parametric_region() + region = region[0].parametric_region() return ParametricIntegral(field, region) except AttributeError: raise ValueError("SymPy cannot determine parametric representation of the region.") diff --git a/sympy/vector/tests/test_integrals.py b/sympy/vector/tests/test_integrals.py index c80b21ac6070..7dbe1d3c4c1a 100644 --- a/sympy/vector/tests/test_integrals.py +++ b/sympy/vector/tests/test_integrals.py @@ -1,12 +1,14 @@ from sympy import sin, cos, pi, S, sqrt +from sympy.testing.pytest import raises from sympy.vector.coordsysrect import CoordSys3D -from sympy.vector.integrals import ParametricIntegral +from sympy.vector.integrals import ParametricIntegral, vector_integrate from sympy.vector.parametricregion import ParametricRegion from sympy.abc import x, y, z, u, v, r, t, theta, phi +from sympy.geometry import Point, Segment, Curve, Circle, Polygon, Plane C = CoordSys3D('C') -def test_lineintegrals(): +def test_parametric_lineintegrals(): halfcircle = ParametricRegion((4*cos(theta), 4*sin(theta)), (theta, -pi/2, pi/2)) assert ParametricIntegral(C.x*C.y**4, halfcircle) == S(8192)/5 @@ -24,7 +26,7 @@ def test_lineintegrals(): field2 = C.y*C.i + C.z*C.j + C.z*C.k assert ParametricIntegral(field2, ParametricRegion((cos(t), sin(t), t**2), (t, 0, pi))) == -5*pi/2 + pi**4/2 -def test_surfaceintegrals(): +def test_parametric_surfaceintegrals(): semisphere = ParametricRegion((2*sin(phi)*cos(theta), 2*sin(phi)*sin(theta), 2*cos(phi)),\ (theta, 0, 2*pi), (phi, 0, pi/2)) @@ -41,7 +43,7 @@ def test_surfaceintegrals(): assert ParametricIntegral(-15.6*C.y*C.k, triangle1) == ParametricIntegral(-15.6*C.y*C.k, triangle2) assert ParametricIntegral(C.z, triangle1) == 10*C.z -def test_volumeintegrals(): +def test_parametric_volumeintegrals(): cube = ParametricRegion((x, y, z), (x, 0, 1), (y, 0, 1), (z, 0, 1)) assert ParametricIntegral(1, cube) == 1 @@ -58,3 +60,35 @@ def test_volumeintegrals(): assert ParametricIntegral(C.x*C.i + C.j - 100*C.k, region_under_plane1) == \ ParametricIntegral(C.x*C.i + C.j - 100*C.k, region_under_plane2) assert ParametricIntegral(2*C.x, region_under_plane2) == -9 + +def test_vector_integrate(): + halfdisc = ParametricRegion((r*cos(theta), r* sin(theta)), (r, -2, 2), (theta, 0, pi)) + assert vector_integrate(C.x**2, halfdisc) == 4*pi + vector_integrate(C.x, ParametricRegion((t, t**2), (t, 2, 3))) == -17*sqrt(17)/12 + 37*sqrt(37)/12 + + assert vector_integrate(C.y**3*C.z, (C.x, 0, 3), (C.y, -1, 4)) == 765*C.z/4 + + s1 = Segment(Point(0, 0), Point(0, 1)) + assert vector_integrate(-15*C.y, s1) == S(-15)/2 + s2 = Segment(Point(4, 3, 9), Point(1, 1, 7)) + assert vector_integrate(C.y*C.i, s2) == -6 + + curve = Curve((sin(t), cos(t)), (t, 0, 2)) + assert vector_integrate(5*C.z, curve) == 10*C.z + + c1 = Circle(Point(2, 3), 6) + assert vector_integrate(C.x*C.y, c1) == 72*pi + c2 = Circle(Point(0, 0), Point(1, 1), Point(1, 0)) + assert vector_integrate(1, c2) == c2.circumference + + triangle = Polygon((0, 0), (1, 0), (1, 1)) + assert vector_integrate(C.x*C.i - 14*C.y*C.j, triangle) == 0 + p1, p2, p3, p4 = [(0, 0), (1, 0), (5, 1), (0, 1)] + poly = Polygon(p1, p2, p3, p4) + assert vector_integrate(-23*C.z, poly) == -161*C.z - 23*sqrt(17)*C.z + + point = Point(2, 3) + assert vector_integrate(C.i*C.y - C.z, point) == ParametricIntegral(C.y*C.i, ParametricRegion((2, 3))) + + pl = Plane(Point(1, 1, 1), Point(2, 3, 4), Point(2, 2, 2)) + raises(ValueError, lambda: vector_integrate(C.x*C.z*C.i + C.k, pl)) From d2dbfa491a41edaf3bf21d359cb256348718d0e6 Mon Sep 17 00:00:00 2001 From: Faisal Riyaz Date: Sat, 27 Jun 2020 00:18:04 +0530 Subject: [PATCH 3/6] Improved docstring for parametric_region --- sympy/geometry/curve.py | 2 +- sympy/geometry/ellipse.py | 2 +- sympy/geometry/line.py | 2 +- sympy/geometry/point.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sympy/geometry/curve.py b/sympy/geometry/curve.py index 4bad3d8540bd..86378ec60ec8 100644 --- a/sympy/geometry/curve.py +++ b/sympy/geometry/curve.py @@ -147,7 +147,7 @@ def arbitrary_point(self, parameter='t'): def parametric_region(self): """ - Returns an object of ParamRegion class representing the Curve. + Returns an object of ParametricRegion class representing the Curve. Examples ======== diff --git a/sympy/geometry/ellipse.py b/sympy/geometry/ellipse.py index ace8437acf40..2276bb89d490 100644 --- a/sympy/geometry/ellipse.py +++ b/sympy/geometry/ellipse.py @@ -249,7 +249,7 @@ def arbitrary_point(self, parameter='t'): def parametric_region(self, parameter='t'): """ - Returns an object of ParamRegion class representing the Ellipse. + Returns an object of ParametricRegion class representing the Ellipse. Examples ======== diff --git a/sympy/geometry/line.py b/sympy/geometry/line.py index 18dc35de3caa..3d1530f1b361 100644 --- a/sympy/geometry/line.py +++ b/sympy/geometry/line.py @@ -1824,7 +1824,7 @@ def _parametric_bounds(self, parameter='t'): def parametric_region(self, parameter='t'): """ - Returns an object of ParamRegion class representing the Segment. + Returns an object of ParametricRegion class representing the Segment. Examples ======== diff --git a/sympy/geometry/point.py b/sympy/geometry/point.py index 85e20e86f947..febd896b0c89 100644 --- a/sympy/geometry/point.py +++ b/sympy/geometry/point.py @@ -614,7 +614,7 @@ def is_concyclic(self, *args): def parametric_region(self): """ - Returns an object of ParamRegion class representing the Point. + Returns an object of ParametricRegion class representing the Point. Examples ======== From e861882e50857eab3e24e022735cbc77a63b607e Mon Sep 17 00:00:00 2001 From: Faisal Riyaz Date: Tue, 30 Jun 2020 18:10:41 +0530 Subject: [PATCH 4/6] Implemented parametric_region function to convert objects of geometry module to parametric region. --- sympy/geometry/curve.py | 20 ------ sympy/geometry/ellipse.py | 20 ------ sympy/geometry/line.py | 31 -------- sympy/geometry/point.py | 16 ----- sympy/geometry/tests/test_line.py | 10 --- sympy/vector/__init__.py | 4 +- sympy/vector/integrals.py | 16 ++--- sympy/vector/parametricregion.py | 78 ++++++++++++++++++++- sympy/vector/tests/test_parametricregion.py | 30 +++++++- 9 files changed, 113 insertions(+), 112 deletions(-) diff --git a/sympy/geometry/curve.py b/sympy/geometry/curve.py index 86378ec60ec8..5f939a33249a 100644 --- a/sympy/geometry/curve.py +++ b/sympy/geometry/curve.py @@ -145,26 +145,6 @@ def arbitrary_point(self, parameter='t'): 'and cannot be used as a parameter.' % tnew.name) return Point(*[w.subs(t, tnew) for w in self.functions]) - def parametric_region(self): - """ - Returns an object of ParametricRegion class representing the Curve. - - Examples - ======== - - >>> from sympy.abc import t - >>> from sympy import Curve - >>> c = Curve((t**3, 4*t), (t, -3, 4)) - >>> c.parametric_region() - ParametricRegion((t**3, 4*t), (t, -3, 4)) - - """ - from sympy.vector import ParametricRegion - - definition = self.arbitrary_point(self.parameter).args - bounds = self.limits - return ParametricRegion(definition, bounds) - @property def free_symbols(self): """Return a set of symbols other than the bound symbols used to diff --git a/sympy/geometry/ellipse.py b/sympy/geometry/ellipse.py index 2276bb89d490..b16a805a50ed 100644 --- a/sympy/geometry/ellipse.py +++ b/sympy/geometry/ellipse.py @@ -247,26 +247,6 @@ def arbitrary_point(self, parameter='t'): return Point(self.center.x + self.hradius*cos(t), self.center.y + self.vradius*sin(t)) - def parametric_region(self, parameter='t'): - """ - Returns an object of ParametricRegion class representing the Ellipse. - - Examples - ======== - - >>> from sympy import Point, Ellipse - >>> e = Ellipse(Point(1, 3), 2, 3) - >>> e.parametric_region() - ParametricRegion((2*cos(t) + 1, 3*sin(t) + 3), (t, 0, 2*pi)) - - """ - from sympy.vector import ParametricRegion - - definition = self.arbitrary_point(parameter).args - t = _symbol(parameter, real=True) - bounds = (t, 0, 2*pi) - return ParametricRegion(definition, bounds) - @property def area(self): """The area of the ellipse. diff --git a/sympy/geometry/line.py b/sympy/geometry/line.py index 3d1530f1b361..33805b37e757 100644 --- a/sympy/geometry/line.py +++ b/sympy/geometry/line.py @@ -33,7 +33,6 @@ from sympy.matrices import Matrix from sympy.sets import Intersection from sympy.simplify.simplify import simplify -from sympy.solvers import solve from sympy.solvers.solveset import linear_coeffs from sympy.utilities.exceptions import SymPyDeprecationWarning from sympy.utilities.misc import Undecidable, filldedent @@ -1811,36 +1810,6 @@ def perpendicular_bisector(self, p=None): return Segment(p2, self.midpoint) return l - def _parametric_bounds(self, parameter='t'): - t = _symbol(parameter, real=True) - definition = self.arbitrary_point().args - - for i in range(0, 3): - lower_bound = solve(definition[i] - self.points[0].args[i], t) - upper_bound = solve(definition[i] - self.points[1].args[i], t) - - if len(lower_bound) == 1 and len(upper_bound) == 1: - return t, lower_bound[0], upper_bound[0] - - def parametric_region(self, parameter='t'): - """ - Returns an object of ParametricRegion class representing the Segment. - - Examples - ======== - - >>> from sympy import Point, Segment - >>> s = Segment(Point(1, 3), Point(2, 6)) - >>> s.parametric_region() - ParametricRegion((t + 1, 3*t + 3), (t, 0, 1)) - - """ - from sympy.vector import ParametricRegion - - definition_tuple = self.arbitrary_point(parameter).args - bounds = self._parametric_bounds() - return ParametricRegion(definition_tuple, bounds) - def plot_interval(self, parameter='t'): """The plot interval for the default geometric plot of the Segment gives values that will produce the full segment in a plot. diff --git a/sympy/geometry/point.py b/sympy/geometry/point.py index febd896b0c89..a8e79b277792 100644 --- a/sympy/geometry/point.py +++ b/sympy/geometry/point.py @@ -612,22 +612,6 @@ def is_concyclic(self, *args): return True return False - def parametric_region(self): - """ - Returns an object of ParametricRegion class representing the Point. - - Examples - ======== - - >>> from sympy import Point - >>> p = Point(2, 5) - >>> p.parametric_region() - ParametricRegion((2, 5)) - - """ - from sympy.vector import ParametricRegion - return ParametricRegion(self.args) - @property def is_nonzero(self): """True if any coordinate is nonzero, False if every coordinate is zero, diff --git a/sympy/geometry/tests/test_line.py b/sympy/geometry/tests/test_line.py index 565b6e035fbf..89af9cfc844d 100644 --- a/sympy/geometry/tests/test_line.py +++ b/sympy/geometry/tests/test_line.py @@ -6,7 +6,6 @@ Point2D, Line2D) from sympy.geometry.line import Undecidable from sympy.geometry.polygon import _asa as asa -from sympy.vector import ParametricRegion from sympy.utilities.iterables import cartes from sympy.testing.pytest import raises, warns @@ -97,15 +96,6 @@ def test_arbitrary_point(): raises(ValueError, (lambda: Line((x, 1), (2, 3)).arbitrary_point(x))) -def test_parametric_region(): - s1 = Segment(Point(0, 0), (1, 0)) - assert s1.parametric_region() == ParametricRegion((t, 0), (t, 0, 1)) - s2 = Segment(Point(1, 2, 3), Point(1, 2, 5)) - assert s2.parametric_region() == ParametricRegion((1, 2, 2*t + 3), (t, 0, 1)) - s3 = Segment(Point(12, 56), Point(12, 56)) - assert s3.parametric_region() == ParametricRegion((12, 56)) - - def test_are_concurrent_2d(): l1 = Line(Point(0, 0), Point(1, 1)) l2 = Line(Point(x1, x1), Point(x1, 1 + x1)) diff --git a/sympy/vector/__init__.py b/sympy/vector/__init__.py index 1353d561b847..dcc78fa8ec26 100644 --- a/sympy/vector/__init__.py +++ b/sympy/vector/__init__.py @@ -14,7 +14,7 @@ from sympy.vector.orienters import (AxisOrienter, BodyOrienter, SpaceOrienter, QuaternionOrienter) from sympy.vector.operators import Gradient, Divergence, Curl, Laplacian, gradient, curl, divergence -from sympy.vector.parametricregion import ParametricRegion +from sympy.vector.parametricregion import (ParametricRegion, parametric_region) from sympy.vector.integrals import (ParametricIntegral, vector_integrate) __all__ = [ @@ -40,5 +40,5 @@ 'Gradient', 'Divergence', 'Curl', 'Laplacian', 'gradient', 'curl', 'divergence', - 'ParametricRegion', 'ParametricIntegral', 'vector_integrate', + 'ParametricRegion', 'parametric_region', 'ParametricIntegral', 'vector_integrate', ] diff --git a/sympy/vector/integrals.py b/sympy/vector/integrals.py index 88ee2e4c855b..4375f5abc681 100644 --- a/sympy/vector/integrals.py +++ b/sympy/vector/integrals.py @@ -1,13 +1,13 @@ -from sympy.core.basic import Basic from sympy import simplify +from sympy.core import Basic, diff from sympy.matrices import Matrix -from sympy.vector import CoordSys3D, Vector, ParametricRegion +from sympy.vector import CoordSys3D, Vector, ParametricRegion, parametric_region from sympy.vector.operators import _get_coord_sys_from_expr from sympy.integrals import Integral, integrate -from sympy.core.function import diff from sympy.utilities.iterables import topological_sort, default_sort_key -from sympy.geometry.entity import GeometryEntity from sympy.geometry import Polygon +from sympy.geometry.entity import GeometryEntity + class ParametricIntegral(Basic): """ @@ -137,6 +137,7 @@ def field(self): def parametricregion(self): return self.args[1] + def vector_integrate(field, *region): """ Compute the integral of a vector/scalar field @@ -178,10 +179,7 @@ def vector_integrate(field, *region): result += vector_integrate(field, s) return result - try: - region = region[0].parametric_region() - return ParametricIntegral(field, region) - except AttributeError: - raise ValueError("SymPy cannot determine parametric representation of the region.") + region = parametric_region(region[0]) + return ParametricIntegral(field, region) return integrate(field, *region) diff --git a/sympy/vector/parametricregion.py b/sympy/vector/parametricregion.py index 9dea6b4a7c99..c5a817cbc0ac 100644 --- a/sympy/vector/parametricregion.py +++ b/sympy/vector/parametricregion.py @@ -1,5 +1,10 @@ -from sympy.core.basic import Basic -from sympy.core.containers import Tuple +from functools import singledispatch +from sympy import pi +from sympy.core import Basic, Tuple +from sympy.core.symbol import _symbol +from sympy.solvers import solve +from sympy.geometry import Point, Segment, Curve, Ellipse + class ParametricRegion(Basic): """ @@ -82,3 +87,72 @@ def parameters(self): @property def dimensions(self): return len(self.limits) + + +@singledispatch +def parametric_region(reg): + """ + Returns an object of ParametricRegion class representing the geometric region. + + Examples + ======== + + >>> from sympy.abc import t + >>> from sympy.vector import parametric_region + >>> from sympy.geometry import Point, Curve, Ellipse, Segment + + >>> p = Point(2, 5) + >>> parametric_region(p) + ParametricRegion((2, 5)) + + >>> c = Curve((t**3, 4*t), (t, -3, 4)) + >>> parametric_region(c) + ParametricRegion((t**3, 4*t), (t, -3, 4)) + + >>> e = Ellipse(Point(1, 3), 2, 3) + >>> parametric_region(e) + ParametricRegion((2*cos(t) + 1, 3*sin(t) + 3), (t, 0, 2*pi)) + + >>> s = Segment(Point(1, 3), Point(2, 6)) + >>> parametric_region(s) + ParametricRegion((t + 1, 3*t + 3), (t, 0, 1)) + + """ + raise ValueError("SymPy cannot determine parametric representation of the region.") + + +@parametric_region.register(Point) +def _(obj): + return ParametricRegion(obj.args) + + +@parametric_region.register(Curve) +def _(obj): + definition = obj.arbitrary_point(obj.parameter).args + bounds = obj.limits + return ParametricRegion(definition, bounds) + + +@parametric_region.register(Ellipse) +def _(obj, parameter='t'): + definition = obj.arbitrary_point(parameter).args + t = _symbol(parameter, real=True) + bounds = (t, 0, 2*pi) + return ParametricRegion(definition, bounds) + + +@parametric_region.register(Segment) +def _(obj, parameter='t'): + t = _symbol(parameter, real=True) + definition = obj.arbitrary_point(t).args + + for i in range(0, 3): + lower_bound = solve(definition[i] - obj.points[0].args[i], t) + upper_bound = solve(definition[i] - obj.points[1].args[i], t) + + if len(lower_bound) == 1 and len(upper_bound) == 1: + bounds = t, lower_bound[0], upper_bound[0] + break + + definition_tuple = obj.arbitrary_point(parameter).args + return ParametricRegion(definition_tuple, bounds) diff --git a/sympy/vector/tests/test_parametricregion.py b/sympy/vector/tests/test_parametricregion.py index 10889a66b311..1faa9c8d5228 100644 --- a/sympy/vector/tests/test_parametricregion.py +++ b/sympy/vector/tests/test_parametricregion.py @@ -1,12 +1,14 @@ from sympy import sin, cos, pi from sympy.vector.coordsysrect import CoordSys3D -from sympy.vector.parametricregion import ParametricRegion +from sympy.vector.parametricregion import ParametricRegion, parametric_region +from sympy.geometry import Point, Segment, Curve, Ellipse, Line, Parabola from sympy.testing.pytest import raises from sympy.abc import a, b, r, t, x, y, z, theta, phi + C = CoordSys3D('C') -def test_parametricregion(): +def test_ParametricRegion(): point = ParametricRegion((3, 4)) assert point.definition == (3, 4) @@ -65,3 +67,27 @@ def test_parametricregion(): raises(ValueError, lambda: ParametricRegion((a*t**2, 2*a*t), (a, -2))) raises(ValueError, lambda: ParametricRegion((a, b), (a**2, sin(b)), (a, 2, 4, 6))) + + +def test_parametric_region(): + + point = Point(-5, 12) + assert parametric_region(point) == ParametricRegion((-5, 12)) + + e = Ellipse(Point(2, 8), 2, 6) + assert parametric_region(e, t) == ParametricRegion((2*cos(t) + 2, 6*sin(t) + 8), (t, 0, 2*pi)) + + c = Curve((t, t**3), (t, 5, 3)) + assert parametric_region(c) == ParametricRegion((t, t**3), (t, 5, 3)) + + s = Segment(Point(2, 11, -6), Point(0, 2, 5)) + assert parametric_region(s, t) == ParametricRegion((2 - 2*t, 11 - 9*t, 11*t - 6), (t, 0, 1)) + s1 = Segment(Point(0, 0), (1, 0)) + assert parametric_region(s1, t) == ParametricRegion((t, 0), (t, 0, 1)) + s2 = Segment(Point(1, 2, 3), Point(1, 2, 5)) + assert parametric_region(s2, t) == ParametricRegion((1, 2, 2*t + 3), (t, 0, 1)) + s3 = Segment(Point(12, 56), Point(12, 56)) + assert parametric_region(s3) == ParametricRegion((12, 56)) + + p1 = Parabola(Point(0, 0), Line(Point(5, 8), Point(7,8))) + raises(ValueError, lambda: parametric_region(p1)) From 12f76a4e95559f0ff241e40cba246b27fbed914b Mon Sep 17 00:00:00 2001 From: Faisal Riyaz Date: Thu, 2 Jul 2020 16:22:42 +0530 Subject: [PATCH 5/6] parametric_region() returns a list of ParametricRegion objects --- sympy/vector/integrals.py | 22 ++++++------- sympy/vector/parametricregion.py | 34 ++++++++++++++------- sympy/vector/tests/test_parametricregion.py | 21 +++++++------ 3 files changed, 44 insertions(+), 33 deletions(-) diff --git a/sympy/vector/integrals.py b/sympy/vector/integrals.py index 4375f5abc681..748d33f49e75 100644 --- a/sympy/vector/integrals.py +++ b/sympy/vector/integrals.py @@ -5,7 +5,6 @@ from sympy.vector.operators import _get_coord_sys_from_expr from sympy.integrals import Integral, integrate from sympy.utilities.iterables import topological_sort, default_sort_key -from sympy.geometry import Polygon from sympy.geometry.entity import GeometryEntity @@ -13,8 +12,7 @@ class ParametricIntegral(Basic): """ Represents integral of a scalar or vector field over a Parametric Region - - Examples +/bin Examples ======== >>> from sympy import cos, sin, pi @@ -34,7 +32,7 @@ class ParametricIntegral(Basic): 8*pi >>> ParametricIntegral(C.j + C.k, ParametricRegion((r*cos(theta), r*sin(theta)), r, theta)) - ParametricIntegral(C.j + C.k, ParametricRegion((r*cos(theta), r*sin(theta)), r, theta)) + 0 """ @@ -50,7 +48,7 @@ def __new__(cls, field, parametricregion): coord_sys = next(iter(coord_set)) if parametricregion.dimensions == 0: - return super().__new__(cls, field, parametricregion) + return 0 base_vectors = coord_sys.base_vectors() base_scalars = coord_sys.base_scalars() @@ -173,13 +171,11 @@ def vector_integrate(field, *region): return ParametricIntegral(field, region[0]) if isinstance(region[0], GeometryEntity): - if isinstance(region[0], Polygon): - result = 0 - for s in region[0].sides: - result += vector_integrate(field, s) - return result - - region = parametric_region(region[0]) - return ParametricIntegral(field, region) + regions_list = parametric_region(region[0]) + + result = 0 + for reg in regions_list: + result += vector_integrate(field, reg) + return result return integrate(field, *region) diff --git a/sympy/vector/parametricregion.py b/sympy/vector/parametricregion.py index c5a817cbc0ac..e9828a672910 100644 --- a/sympy/vector/parametricregion.py +++ b/sympy/vector/parametricregion.py @@ -3,7 +3,7 @@ from sympy.core import Basic, Tuple from sympy.core.symbol import _symbol from sympy.solvers import solve -from sympy.geometry import Point, Segment, Curve, Ellipse +from sympy.geometry import Point, Segment, Curve, Ellipse, Polygon class ParametricRegion(Basic): @@ -92,30 +92,36 @@ def dimensions(self): @singledispatch def parametric_region(reg): """ - Returns an object of ParametricRegion class representing the geometric region. + Returns a list of ParametricRegion objects representing the geometric region. Examples ======== >>> from sympy.abc import t >>> from sympy.vector import parametric_region - >>> from sympy.geometry import Point, Curve, Ellipse, Segment + >>> from sympy.geometry import Point, Curve, Ellipse, Segment, Polygon >>> p = Point(2, 5) >>> parametric_region(p) - ParametricRegion((2, 5)) + [ParametricRegion((2, 5))] >>> c = Curve((t**3, 4*t), (t, -3, 4)) >>> parametric_region(c) - ParametricRegion((t**3, 4*t), (t, -3, 4)) + [ParametricRegion((t**3, 4*t), (t, -3, 4))] >>> e = Ellipse(Point(1, 3), 2, 3) >>> parametric_region(e) - ParametricRegion((2*cos(t) + 1, 3*sin(t) + 3), (t, 0, 2*pi)) + [ParametricRegion((2*cos(t) + 1, 3*sin(t) + 3), (t, 0, 2*pi))] >>> s = Segment(Point(1, 3), Point(2, 6)) >>> parametric_region(s) - ParametricRegion((t + 1, 3*t + 3), (t, 0, 1)) + [ParametricRegion((t + 1, 3*t + 3), (t, 0, 1))] + + >>> p1, p2, p3, p4 = [(0, 1), (2, -3), (5, 3), (-2, 3)] + >>> poly = Polygon(p1, p2, p3, p4) + >>> parametric_region(poly) + [ParametricRegion((2*t, 1 - 4*t), (t, 0, 1)), ParametricRegion((3*t + 2, 6*t - 3), (t, 0, 1)),\ + ParametricRegion((5 - 7*t, 3), (t, 0, 1)), ParametricRegion((2*t - 2, 3 - 2*t), (t, 0, 1))] """ raise ValueError("SymPy cannot determine parametric representation of the region.") @@ -123,14 +129,14 @@ def parametric_region(reg): @parametric_region.register(Point) def _(obj): - return ParametricRegion(obj.args) + return [ParametricRegion(obj.args)] @parametric_region.register(Curve) def _(obj): definition = obj.arbitrary_point(obj.parameter).args bounds = obj.limits - return ParametricRegion(definition, bounds) + return [ParametricRegion(definition, bounds)] @parametric_region.register(Ellipse) @@ -138,7 +144,7 @@ def _(obj, parameter='t'): definition = obj.arbitrary_point(parameter).args t = _symbol(parameter, real=True) bounds = (t, 0, 2*pi) - return ParametricRegion(definition, bounds) + return [ParametricRegion(definition, bounds)] @parametric_region.register(Segment) @@ -155,4 +161,10 @@ def _(obj, parameter='t'): break definition_tuple = obj.arbitrary_point(parameter).args - return ParametricRegion(definition_tuple, bounds) + return [ParametricRegion(definition_tuple, bounds)] + + +@parametric_region.register(Polygon) +def _(obj, parameter='t'): + l = [parametric_region(side, parameter)[0] for side in obj.sides] + return l diff --git a/sympy/vector/tests/test_parametricregion.py b/sympy/vector/tests/test_parametricregion.py index 1faa9c8d5228..9ad10ea28ee9 100644 --- a/sympy/vector/tests/test_parametricregion.py +++ b/sympy/vector/tests/test_parametricregion.py @@ -1,7 +1,7 @@ from sympy import sin, cos, pi from sympy.vector.coordsysrect import CoordSys3D from sympy.vector.parametricregion import ParametricRegion, parametric_region -from sympy.geometry import Point, Segment, Curve, Ellipse, Line, Parabola +from sympy.geometry import Point, Segment, Curve, Ellipse, Line, Parabola, Polygon from sympy.testing.pytest import raises from sympy.abc import a, b, r, t, x, y, z, theta, phi @@ -44,7 +44,7 @@ def test_ParametricRegion(): assert circle.definition == (r*cos(theta), r*sin(theta)) assert circle.dimensions == 1 - halfdisc = ParametricRegion((r*cos(theta), r* sin(theta)), (r, -2, 2), (theta, 0, pi)) + halfdisc = ParametricRegion((r*cos(theta), r*sin(theta)), (r, -2, 2), (theta, 0, pi)) assert halfdisc.definition == (r*cos(theta), r*sin(theta)) assert halfdisc.parameters == (r, theta) assert halfdisc.limits == {r: (-2, 2), theta: (0, pi)} @@ -72,22 +72,25 @@ def test_ParametricRegion(): def test_parametric_region(): point = Point(-5, 12) - assert parametric_region(point) == ParametricRegion((-5, 12)) + assert parametric_region(point) == [ParametricRegion((-5, 12))] e = Ellipse(Point(2, 8), 2, 6) - assert parametric_region(e, t) == ParametricRegion((2*cos(t) + 2, 6*sin(t) + 8), (t, 0, 2*pi)) + assert parametric_region(e, t) == [ParametricRegion((2*cos(t) + 2, 6*sin(t) + 8), (t, 0, 2*pi))] c = Curve((t, t**3), (t, 5, 3)) - assert parametric_region(c) == ParametricRegion((t, t**3), (t, 5, 3)) + assert parametric_region(c) == [ParametricRegion((t, t**3), (t, 5, 3))] s = Segment(Point(2, 11, -6), Point(0, 2, 5)) - assert parametric_region(s, t) == ParametricRegion((2 - 2*t, 11 - 9*t, 11*t - 6), (t, 0, 1)) + assert parametric_region(s, t) == [ParametricRegion((2 - 2*t, 11 - 9*t, 11*t - 6), (t, 0, 1))] s1 = Segment(Point(0, 0), (1, 0)) - assert parametric_region(s1, t) == ParametricRegion((t, 0), (t, 0, 1)) + assert parametric_region(s1, t) == [ParametricRegion((t, 0), (t, 0, 1))] s2 = Segment(Point(1, 2, 3), Point(1, 2, 5)) - assert parametric_region(s2, t) == ParametricRegion((1, 2, 2*t + 3), (t, 0, 1)) + assert parametric_region(s2, t) == [ParametricRegion((1, 2, 2*t + 3), (t, 0, 1))] s3 = Segment(Point(12, 56), Point(12, 56)) - assert parametric_region(s3) == ParametricRegion((12, 56)) + assert parametric_region(s3) == [ParametricRegion((12, 56))] + + poly = Polygon((1,3), (-3, 8), (2, 4)) + assert parametric_region(poly, t) == [ParametricRegion((1 - 4*t, 5*t + 3), (t, 0, 1)), ParametricRegion((5*t - 3, 8 - 4*t), (t, 0, 1)), ParametricRegion((2 - t, 4 - t), (t, 0, 1))] p1 = Parabola(Point(0, 0), Line(Point(5, 8), Point(7,8))) raises(ValueError, lambda: parametric_region(p1)) From 15e551c356b73caa9856f69b6e81508c67c04a51 Mon Sep 17 00:00:00 2001 From: Faisal Riyaz Date: Fri, 3 Jul 2020 10:56:46 +0530 Subject: [PATCH 6/6] Rename parametric_region to parametric_region_list --- sympy/vector/__init__.py | 4 ++-- sympy/vector/integrals.py | 11 +++++---- sympy/vector/parametricregion.py | 26 ++++++++++----------- sympy/vector/tests/test_parametricregion.py | 22 ++++++++--------- 4 files changed, 32 insertions(+), 31 deletions(-) diff --git a/sympy/vector/__init__.py b/sympy/vector/__init__.py index dcc78fa8ec26..718cb9575cad 100644 --- a/sympy/vector/__init__.py +++ b/sympy/vector/__init__.py @@ -14,7 +14,7 @@ from sympy.vector.orienters import (AxisOrienter, BodyOrienter, SpaceOrienter, QuaternionOrienter) from sympy.vector.operators import Gradient, Divergence, Curl, Laplacian, gradient, curl, divergence -from sympy.vector.parametricregion import (ParametricRegion, parametric_region) +from sympy.vector.parametricregion import (ParametricRegion, parametric_region_list) from sympy.vector.integrals import (ParametricIntegral, vector_integrate) __all__ = [ @@ -40,5 +40,5 @@ 'Gradient', 'Divergence', 'Curl', 'Laplacian', 'gradient', 'curl', 'divergence', - 'ParametricRegion', 'parametric_region', 'ParametricIntegral', 'vector_integrate', + 'ParametricRegion', 'parametric_region_list', 'ParametricIntegral', 'vector_integrate', ] diff --git a/sympy/vector/integrals.py b/sympy/vector/integrals.py index 748d33f49e75..586cc19d982b 100644 --- a/sympy/vector/integrals.py +++ b/sympy/vector/integrals.py @@ -1,7 +1,7 @@ -from sympy import simplify +from sympy import S, simplify from sympy.core import Basic, diff from sympy.matrices import Matrix -from sympy.vector import CoordSys3D, Vector, ParametricRegion, parametric_region +from sympy.vector import CoordSys3D, Vector, ParametricRegion, parametric_region_list from sympy.vector.operators import _get_coord_sys_from_expr from sympy.integrals import Integral, integrate from sympy.utilities.iterables import topological_sort, default_sort_key @@ -12,7 +12,8 @@ class ParametricIntegral(Basic): """ Represents integral of a scalar or vector field over a Parametric Region -/bin Examples + + Examples ======== >>> from sympy import cos, sin, pi @@ -48,7 +49,7 @@ def __new__(cls, field, parametricregion): coord_sys = next(iter(coord_set)) if parametricregion.dimensions == 0: - return 0 + return S.Zero base_vectors = coord_sys.base_vectors() base_scalars = coord_sys.base_scalars() @@ -171,7 +172,7 @@ def vector_integrate(field, *region): return ParametricIntegral(field, region[0]) if isinstance(region[0], GeometryEntity): - regions_list = parametric_region(region[0]) + regions_list = parametric_region_list(region[0]) result = 0 for reg in regions_list: diff --git a/sympy/vector/parametricregion.py b/sympy/vector/parametricregion.py index e9828a672910..1ced7aa0d164 100644 --- a/sympy/vector/parametricregion.py +++ b/sympy/vector/parametricregion.py @@ -90,7 +90,7 @@ def dimensions(self): @singledispatch -def parametric_region(reg): +def parametric_region_list(reg): """ Returns a list of ParametricRegion objects representing the geometric region. @@ -98,28 +98,28 @@ def parametric_region(reg): ======== >>> from sympy.abc import t - >>> from sympy.vector import parametric_region + >>> from sympy.vector import parametric_region_list >>> from sympy.geometry import Point, Curve, Ellipse, Segment, Polygon >>> p = Point(2, 5) - >>> parametric_region(p) + >>> parametric_region_list(p) [ParametricRegion((2, 5))] >>> c = Curve((t**3, 4*t), (t, -3, 4)) - >>> parametric_region(c) + >>> parametric_region_list(c) [ParametricRegion((t**3, 4*t), (t, -3, 4))] >>> e = Ellipse(Point(1, 3), 2, 3) - >>> parametric_region(e) + >>> parametric_region_list(e) [ParametricRegion((2*cos(t) + 1, 3*sin(t) + 3), (t, 0, 2*pi))] >>> s = Segment(Point(1, 3), Point(2, 6)) - >>> parametric_region(s) + >>> parametric_region_list(s) [ParametricRegion((t + 1, 3*t + 3), (t, 0, 1))] >>> p1, p2, p3, p4 = [(0, 1), (2, -3), (5, 3), (-2, 3)] >>> poly = Polygon(p1, p2, p3, p4) - >>> parametric_region(poly) + >>> parametric_region_list(poly) [ParametricRegion((2*t, 1 - 4*t), (t, 0, 1)), ParametricRegion((3*t + 2, 6*t - 3), (t, 0, 1)),\ ParametricRegion((5 - 7*t, 3), (t, 0, 1)), ParametricRegion((2*t - 2, 3 - 2*t), (t, 0, 1))] @@ -127,19 +127,19 @@ def parametric_region(reg): raise ValueError("SymPy cannot determine parametric representation of the region.") -@parametric_region.register(Point) +@parametric_region_list.register(Point) def _(obj): return [ParametricRegion(obj.args)] -@parametric_region.register(Curve) +@parametric_region_list.register(Curve) def _(obj): definition = obj.arbitrary_point(obj.parameter).args bounds = obj.limits return [ParametricRegion(definition, bounds)] -@parametric_region.register(Ellipse) +@parametric_region_list.register(Ellipse) def _(obj, parameter='t'): definition = obj.arbitrary_point(parameter).args t = _symbol(parameter, real=True) @@ -147,7 +147,7 @@ def _(obj, parameter='t'): return [ParametricRegion(definition, bounds)] -@parametric_region.register(Segment) +@parametric_region_list.register(Segment) def _(obj, parameter='t'): t = _symbol(parameter, real=True) definition = obj.arbitrary_point(t).args @@ -164,7 +164,7 @@ def _(obj, parameter='t'): return [ParametricRegion(definition_tuple, bounds)] -@parametric_region.register(Polygon) +@parametric_region_list.register(Polygon) def _(obj, parameter='t'): - l = [parametric_region(side, parameter)[0] for side in obj.sides] + l = [parametric_region_list(side, parameter)[0] for side in obj.sides] return l diff --git a/sympy/vector/tests/test_parametricregion.py b/sympy/vector/tests/test_parametricregion.py index 9ad10ea28ee9..68cd82db5557 100644 --- a/sympy/vector/tests/test_parametricregion.py +++ b/sympy/vector/tests/test_parametricregion.py @@ -1,6 +1,6 @@ from sympy import sin, cos, pi from sympy.vector.coordsysrect import CoordSys3D -from sympy.vector.parametricregion import ParametricRegion, parametric_region +from sympy.vector.parametricregion import ParametricRegion, parametric_region_list from sympy.geometry import Point, Segment, Curve, Ellipse, Line, Parabola, Polygon from sympy.testing.pytest import raises from sympy.abc import a, b, r, t, x, y, z, theta, phi @@ -69,28 +69,28 @@ def test_ParametricRegion(): raises(ValueError, lambda: ParametricRegion((a, b), (a**2, sin(b)), (a, 2, 4, 6))) -def test_parametric_region(): +def test_parametric_region_list(): point = Point(-5, 12) - assert parametric_region(point) == [ParametricRegion((-5, 12))] + assert parametric_region_list(point) == [ParametricRegion((-5, 12))] e = Ellipse(Point(2, 8), 2, 6) - assert parametric_region(e, t) == [ParametricRegion((2*cos(t) + 2, 6*sin(t) + 8), (t, 0, 2*pi))] + assert parametric_region_list(e, t) == [ParametricRegion((2*cos(t) + 2, 6*sin(t) + 8), (t, 0, 2*pi))] c = Curve((t, t**3), (t, 5, 3)) - assert parametric_region(c) == [ParametricRegion((t, t**3), (t, 5, 3))] + assert parametric_region_list(c) == [ParametricRegion((t, t**3), (t, 5, 3))] s = Segment(Point(2, 11, -6), Point(0, 2, 5)) - assert parametric_region(s, t) == [ParametricRegion((2 - 2*t, 11 - 9*t, 11*t - 6), (t, 0, 1))] + assert parametric_region_list(s, t) == [ParametricRegion((2 - 2*t, 11 - 9*t, 11*t - 6), (t, 0, 1))] s1 = Segment(Point(0, 0), (1, 0)) - assert parametric_region(s1, t) == [ParametricRegion((t, 0), (t, 0, 1))] + assert parametric_region_list(s1, t) == [ParametricRegion((t, 0), (t, 0, 1))] s2 = Segment(Point(1, 2, 3), Point(1, 2, 5)) - assert parametric_region(s2, t) == [ParametricRegion((1, 2, 2*t + 3), (t, 0, 1))] + assert parametric_region_list(s2, t) == [ParametricRegion((1, 2, 2*t + 3), (t, 0, 1))] s3 = Segment(Point(12, 56), Point(12, 56)) - assert parametric_region(s3) == [ParametricRegion((12, 56))] + assert parametric_region_list(s3) == [ParametricRegion((12, 56))] poly = Polygon((1,3), (-3, 8), (2, 4)) - assert parametric_region(poly, t) == [ParametricRegion((1 - 4*t, 5*t + 3), (t, 0, 1)), ParametricRegion((5*t - 3, 8 - 4*t), (t, 0, 1)), ParametricRegion((2 - t, 4 - t), (t, 0, 1))] + assert parametric_region_list(poly, t) == [ParametricRegion((1 - 4*t, 5*t + 3), (t, 0, 1)), ParametricRegion((5*t - 3, 8 - 4*t), (t, 0, 1)), ParametricRegion((2 - t, 4 - t), (t, 0, 1))] p1 = Parabola(Point(0, 0), Line(Point(5, 8), Point(7,8))) - raises(ValueError, lambda: parametric_region(p1)) + raises(ValueError, lambda: parametric_region_list(p1))