Example #1
0
    def equation(self, x='x', y='y'):
        """The equation of the line: ax + by + c.

        Parameters
        ----------
        x : str, optional
            The name to use for the x-axis, default value is 'x'.
        y : str, optional
            The name to use for the y-axis, default value is 'y'.

        Returns
        -------
        equation : sympy expression

        Examples
        --------
        >>> from sympy import Point, Line
        >>> p1, p2 = Point(1, 0), Point(5, 3)
        >>> l1 = Line(p1, p2)
        >>> l1.equation()
        -3*x + 4*y + 3

        """
        x, y = _symbol(x), _symbol(y)
        p1, p2 = self.points
        if p1[0] == p2[0]:
            return x - p1[0]
        elif p1[1] == p2[1]:
            return y - p1[1]

        a, b, c = self.coefficients
        return simplify(a*x + b*y + c)
Example #2
0
    def equation(self, x='x', y='y'):
        """The equation of the circle.

        Parameters
        ==========

        x : str or Symbol, optional
            Default value is 'x'.
        y : str or Symbol, optional
            Default value is 'y'.

        Returns
        =======

        equation : SymPy expression

        Examples
        ========

        >>> from sympy import Point, Circle
        >>> c1 = Circle(Point(0, 0), 5)
        >>> c1.equation()
        x**2 + y**2 - 25

        """
        x = _symbol(x)
        y = _symbol(y)
        t1 = (x - self.center.x)**2
        t2 = (y - self.center.y)**2
        return t1 + t2 - self.major**2
Example #3
0
    def equation(self, x='x', y='y'):
        """The equation of the ellipse.

        Parameters
        ==========

        x : str, optional
            Label for the x-axis. Default value is 'x'.
        y : str, optional
            Label for the y-axis. Default value is 'y'.

        Returns
        =======

        equation : sympy expression

        See Also
        ========

        arbitrary_point : Returns parameterized point on ellipse

        Examples
        ========

        >>> from sympy import Point, Ellipse
        >>> e1 = Ellipse(Point(1, 0), 3, 2)
        >>> e1.equation()
        y**2/4 + (x/3 - 1/3)**2 - 1

        """
        x = _symbol(x)
        y = _symbol(y)
        t1 = ((x - self.center.x) / self.hradius)**2
        t2 = ((y - self.center.y) / self.vradius)**2
        return t1 + t2 - 1
Example #4
0
    def equation(self, x="x", y="y"):
        """The equation of the ellipse.

        Parameters
        ----------
        x : str, optional
            Label for the x-axis. Default value is 'x'.
        y : str, optional
            Label for the y-axis. Default value is 'y'.

        Returns
        -------
        equation : sympy expression

        Examples
        --------
        >>> from sympy import Point, Ellipse
        >>> e1 = Ellipse(Point(1, 0), 3, 2)
        >>> e1.equation()
        y**2/4 + (x/3 - 1/3)**2 - 1

        """
        x = _symbol(x)
        y = _symbol(y)
        t1 = ((x - self.center[0]) / self.hradius) ** 2
        t2 = ((y - self.center[1]) / self.vradius) ** 2
        return t1 + t2 - 1
Example #5
0
    def equation(self, x="x", y="y"):
        """The equation of the circle.

        Parameters
        ----------
        x : str or Symbol, optional
            Default value is 'x'.
        y : str or Symbol, optional
            Default value is 'y'.

        Returns
        -------
        equation : sympy expression

        Examples
        --------
        >>> from sympy import Point, Circle
        >>> c1 = Circle(Point(0, 0), 5)
        >>> c1.equation()
        x**2 + y**2 - 25

        """
        x = _symbol(x)
        y = _symbol(y)
        t1 = (x - self.center[0]) ** 2
        t2 = (y - self.center[1]) ** 2
        return t1 + t2 - self.major ** 2
Example #6
0
File: line.py Project: Maihj/sympy
    def plot_interval(self, parameter='t'):
        """The plot interval for the default geometric plot of the Ray. Gives
        values that will produce a ray that is 10 units long (where a unit is
        the distance between the two points that define the ray).

        Parameters
        ==========

        parameter : str, optional
            Default value is 't'.

        Returns
        =======

        plot_interval : list
            [parameter, lower_bound, upper_bound]

        Examples
        ========

        >>> from sympy import Point, Ray, pi
        >>> r = Ray((0, 0), angle=pi/4)
        >>> r.plot_interval()
        [t, 0, 10]

        """
        t = _symbol(parameter)
        return [t, 0, 10]
Example #7
0
    def plot_interval(self, parameter='t'):
        """The plot interval for the default geometric plot of the curve.

        Parameters
        ----------
        parameter : str or Symbol, optional
            Default value is 't';
            otherwise the provided symbol is used.

        Returns
        -------
        plot_interval : list (plot interval)
            [parameter, lower_bound, upper_bound]

        Examples
        --------
        >>> from sympy import Curve, sin
        >>> from sympy.abc import x, t, s
        >>> Curve((x, sin(x)), (x, 1, 2)).plot_interval()
        [t, 1, 2]
        >>> Curve((x, sin(x)), (x, 1, 2)).plot_interval(s)
        [s, 1, 2]

        """
        t = _symbol(parameter, self.parameter)
        return [t] + list(self.limits[1:])
Example #8
0
    def plot_interval(self, parameter='t'):
        """The plot interval for the default geometric plot of line.

        Parameters
        ==========

        parameter : str, optional
            Default value is 't'.

        Returns
        =======

        plot_interval : list (plot interval)
            [parameter, lower_bound, upper_bound]

        Examples
        ========

        >>> from sympy import Point, Line
        >>> p1, p2 = Point(0, 0), Point(5, 3)
        >>> l1 = Line(p1, p2)
        >>> l1.plot_interval()
        [t, -5, 5]

        """
        t = _symbol(parameter)
        return [t, -5, 5]
Example #9
0
    def plot_interval(self, parameter='t'):
        """The plot interval for the default geometric plot of the Segment.

        Parameters
        ==========

        parameter : str, optional
            Default value is 't'.

        Returns
        =======

        plot_interval : list
            [parameter, lower_bound, upper_bound]

        Examples
        ========

        >>> from sympy import Point, Segment
        >>> p1, p2 = Point(0, 0), Point(5, 3)
        >>> s1 = Segment(p1, p2)
        >>> s1.plot_interval()
        [t, 0, 1]

        """
        t = _symbol(parameter)
        return [t, 0, 1]
Example #10
0
    def plot_interval(self, parameter='t'):
        """The plot interval for the default geometric plot of the Ellipse.

        Parameters
        ==========

        parameter : str, optional
            Default value is 't'.

        Returns
        =======

        plot_interval : list
            [parameter, lower_bound, upper_bound]

        Examples
        ========

        >>> from sympy import Point, Ellipse
        >>> e1 = Ellipse(Point(0, 0), 3, 2)
        >>> e1.plot_interval()
        [t, -pi, pi]

        """
        t = _symbol(parameter)
        return [t, -S.Pi, S.Pi]
Example #11
0
    def arbitrary_point(self, parameter="t"):
        """A parameterized point on the ellipse.

        Parameters
        ----------
        parameter : str, optional
            Default value is 't'.

        Returns
        -------
        arbitrary_point : Point

        Raises
        ------
        ValueError
            When `parameter` already appears in the functions.

        See Also
        --------
        Point

        Examples
        --------
        >>> from sympy import Point, Ellipse
        >>> e1 = Ellipse(Point(0, 0), 3, 2)
        >>> e1.arbitrary_point()
        Point(3*cos(t), 2*sin(t))

        """
        t = _symbol(parameter)
        if t.name in (f.name for f in self.free_symbols):
            raise ValueError("Symbol %s already appears in object and cannot be used as a parameter." % t.name)
        return Point(self.center[0] + self.hradius * C.cos(t), self.center[1] + self.vradius * C.sin(t))
Example #12
0
    def plot_interval(self, parameter='t'):
        """The plot interval for the default geometric plot of the Ray.

        Parameters
        ==========

        parameter : str, optional
            Default value is 't'.

        Returns
        =======

        plot_interval : list
            [parameter, lower_bound, upper_bound]

        Examples
        ========

        >>> from sympy import Point, Ray, pi
        >>> r = Ray((0, 0), angle=pi/4)
        >>> r.plot_interval()
        [t, 0, 5*sqrt(2)/(1 + 5*sqrt(2))]

        """
        t = _symbol(parameter)
        p = self.arbitrary_point(t)
        # get a t corresponding to length of 10
        want = 10
        u = Segment(self.p1, p.subs(t, S.Half)).length  # gives unit length
        t_need = want/u
        return [t, 0, t_need/(1 + t_need)]
Example #13
0
File: line.py Project: Maihj/sympy
    def plot_interval(self, parameter='t'):
        """The plot interval for the default geometric plot of line. Gives
        values that will produce a line that is +/- 5 units long (where a
        unit is the distance between the two points that define the line).

        Parameters
        ==========

        parameter : str, optional
            Default value is 't'.

        Returns
        =======

        plot_interval : list (plot interval)
            [parameter, lower_bound, upper_bound]

        Examples
        ========

        >>> from sympy import Point, Line
        >>> p1, p2 = Point(0, 0), Point(5, 3)
        >>> l1 = Line(p1, p2)
        >>> l1.plot_interval()
        [t, -5, 5]

        """
        t = _symbol(parameter)
        return [t, -5, 5]
Example #14
0
    def arbitrary_point(self, parameter='t'):
        """A parameterized point on the Segment.

        Parameters
        ==========

        parameter : str, optional
            The name of the parameter which will be used for the parametric
            point. The default value is 't'.

        Returns
        =======

        point : Point


        Parameters
        ==========

        parameter : str, optional
            The name of the parameter which will be used for the parametric
            point. The default value is 't'.

        Returns
        =======

        point : Point

        Raises
        ======

        ValueError
            When ``parameter`` already appears in the Segment's definition.

        See Also
        ========

        sympy.geometry.point.Point

        Examples
        ========

        >>> from sympy import Point, Segment
        >>> p1, p2 = Point(1, 0), Point(5, 3)
        >>> s1 = Segment(p1, p2)
        >>> s1.arbitrary_point()
        Point(4*t + 1, 3*t)

        """
        t = _symbol(parameter)
        if t.name in (f.name for f in self.free_symbols):
            raise ValueError('Symbol %s already appears in object and cannot be used as a parameter.' % t.name)
        x = simplify(self.p1.x + t*(self.p2.x - self.p1.x))
        y = simplify(self.p1.y + t*(self.p2.y - self.p1.y))
        return Point(x, y)
Example #15
0
    def arbitrary_point(self, parameter='t'):
        """
        A parameterized point on the curve.

        Parameters
        ==========

        parameter : str or Symbol, optional
            Default value is 't';
            the Curve's parameter is selected with None or self.parameter
            otherwise the provided symbol is used.

        Returns
        =======

        arbitrary_point : Point

        Raises
        ======

        ValueError
            When `parameter` already appears in the functions.

        See Also
        ========

        sympy.geometry.point.Point

        Examples
        ========

        >>> from sympy import Symbol
        >>> from sympy.abc import s
        >>> from sympy.geometry import Curve
        >>> C = Curve([2*s, s**2], (s, 0, 2))
        >>> C.arbitrary_point()
        Point(2*t, t**2)
        >>> C.arbitrary_point(C.parameter)
        Point(2*s, s**2)
        >>> C.arbitrary_point(None)
        Point(2*s, s**2)
        >>> C.arbitrary_point(Symbol('a'))
        Point(2*a, a**2)

        """
        if parameter is None:
            return Point(*self.functions)

        tnew = _symbol(parameter, self.parameter)
        t = self.parameter
        if (tnew.name != t.name and
            tnew.name in (f.name for f in self.free_symbols)):
            raise ValueError('Symbol %s already appears in object '
                'and cannot be used as a parameter.' % tnew.name)
        return Point(*[w.subs(t, tnew) for w in self.functions])
Example #16
0
    def equation(self, x='x', y='y'):
        """The equation of the line: ax + by + c.

        Parameters
        ==========

        x : str, optional
            The name to use for the x-axis, default value is 'x'.
        y : str, optional
            The name to use for the y-axis, default value is 'y'.

        Returns
        =======

        equation : sympy expression

        See Also
        ========

        LinearEntity.coefficients

        Examples
        ========

        >>> from sympy import Point, Line
        >>> p1, p2 = Point(1, 0), Point(5, 3)
        >>> l1 = Line(p1, p2)
        >>> l1.equation()
        -3*x + 4*y + 3

        """
        x, y = _symbol(x), _symbol(y)
        p1, p2 = self.points
        if p1.x == p2.x:
            return x - p1.x
        elif p1.y == p2.y:
            return y - p1.y

        a, b, c = self.coefficients
        return simplify(a*x + b*y + c)
Example #17
0
    def arbitrary_point(self, parameter='t'):
        """A parameterized point on the polygon.

        The parameter, varying from 0 to 1, assigns points to the position on
        the perimeter that is that fraction of the total perimeter. So the
        point evaluated at t=1/2 would return the point from the first vertex
        that is 1/2 way around the polygon.

        Parameters
        ----------
        parameter : str, optional
            Default value is 't'.

        Returns
        -------
        arbitrary_point : Point

        Raises
        ------
        ValueError
            When `parameter` already appears in the Polygon's definition.

        See Also
        --------
        Point

        Examples
        --------
        >>> from sympy import Polygon, S, Symbol
        >>> t = Symbol('t', real=True)
        >>> tri = Polygon((0, 0), (1, 0), (1, 1))
        >>> p = tri.arbitrary_point('t')
        >>> perimeter = tri.perimeter
        >>> s1, s2 = [s.length for s in tri.sides[:2]]
        >>> p.subs(t, (s1 + s2/2)/perimeter)
        Point(1, 1/2)

        """
        t = _symbol(parameter)
        if t.name in (f.name for f in self.free_symbols):
            raise ValueError('Symbol %s already appears in object and cannot be used as a parameter.' % t.name)
        sides = []
        perimeter = self.perimeter
        perim_fraction_start = 0
        for s in self.sides:
            side_perim_fraction = s.length/perimeter
            perim_fraction_end = perim_fraction_start + side_perim_fraction
            pt  = s.arbitrary_point(parameter).subs(
                  t, (t - perim_fraction_start)/side_perim_fraction)
            sides.append((pt, (perim_fraction_start <= t < perim_fraction_end)))
            perim_fraction_start = perim_fraction_end
        return Piecewise(*sides)
Example #18
0
    def arbitrary_point(self, parameter='t'):
        """A parameterized point on the Segment.

        Parameters
        ----------
        parameter : str, optional
            The name of the parameter which will be used for the parametric
            point. The default value is 't'.

        Returns
        -------
        point : Point


        Parameters
        ----------
        parameter : str, optional
            The name of the parameter which will be used for the parametric
            point. The default value is 't'.

        Returns
        -------
        point : Point

        Raises
        ------
        ValueError
            When `parameter` already appears in the Segment's definition.

        See Also
        --------
        Point

        Examples
        --------
        >>> from sympy import Point, Segment
        >>> p1, p2 = Point(1, 0), Point(5, 3)
        >>> s1 = Segment(p1, p2)
        >>> s1.arbitrary_point()
        Point(1 + 4*t, 3*t)

        """
        t = _symbol(parameter)
        if t.name in (f.name for f in self.free_symbols):
            raise ValueError('Symbol %s already appears in object and cannot be used as a parameter.' % t.name)
        x = simplify(self.p1[0] + t*(self.p2[0] - self.p1[0]))
        y = simplify(self.p1[1] + t*(self.p2[1] - self.p1[1]))
        return Point(x, y)
Example #19
0
File: line.py Project: Maihj/sympy
    def arbitrary_point(self, parameter='t'):
        """A parameterized point on the Line.

        Parameters
        ==========

        parameter : str, optional
            The name of the parameter which will be used for the parametric
            point. The default value is 't'. When this parameter is 0, the
            first point used to define the line will be returned, and when
            it is 1 the second point will be returned.

        Returns
        =======

        point : Point

        Raises
        ======

        ValueError
            When ``parameter`` already appears in the Line's definition.

        See Also
        ========

        sympy.geometry.point.Point

        Examples
        ========

        >>> from sympy import Point, Line
        >>> p1, p2 = Point(1, 0), Point(5, 3)
        >>> l1 = Line(p1, p2)
        >>> l1.arbitrary_point()
        Point(4*t + 1, 3*t)

        """
        t = _symbol(parameter)
        if t.name in (f.name for f in self.free_symbols):
            raise ValueError('Symbol %s already appears in object '
            'and cannot be used as a parameter.' % t.name)
        x = simplify(self.p1.x + t*(self.p2.x - self.p1.x))
        y = simplify(self.p1.y + t*(self.p2.y - self.p1.y))
        return Point(x, y)
Example #20
0
    def random_point(self):
        """A random point on the ellipse.

        Returns
        =======

        point : Point

        See Also
        ========

        sympy.geometry.point.Point
        arbitrary_point : Returns parameterized point on ellipse

        Notes
        -----

        A random point may not appear to be on the ellipse, ie, `p in e` may
        return False. This is because the coordinates of the point will be
        floating point values, and when these values are substituted into the
        equation for the ellipse the result may not be zero because of floating
        point rounding error.

        Examples
        ========

        >>> from sympy import Point, Ellipse
        >>> e1 = Ellipse(Point(0, 0), 3, 2)
        >>> p1 = e1.random_point()
        >>> # a random point may not appear to be on the ellipse because of
        >>> # floating point rounding error
        >>> p1 in e1 # doctest: +SKIP
        True
        >>> p1 # doctest +ELLIPSIS
        Point(...)

        """
        from random import random

        t = _symbol("t")
        x, y = self.arbitrary_point(t).args
        # get a random value in [-pi, pi)
        subs_val = float(S.Pi) * (2 * random() - 1)
        return Point(x.subs(t, subs_val), y.subs(t, subs_val))
Example #21
0
    def plot_interval(self, parameter='t'):
        """The plot interval for the default geometric plot of line.

        Parameters
        ----------
        parameter : str, optional
            Default value is 't'.

        Returns
        -------
        plot_interval : list (plot interval)
            [parameter, lower_bound, upper_bound]

        Examples
        --------
        >>> from sympy import Point, Line
        >>> p1, p2 = Point(0, 0), Point(5, 3)
        >>> l1 = Line(p1, p2)
        >>> l1.plot_interval()
        [t, -5, 5]

        """
        t = _symbol(parameter)
        return [t, -5, 5]
Example #22
0
    def arbitrary_point(self, parameter='t'):
        """A parameterized point on the ellipse.

        Parameters
        ==========
        parameter : str, optional
            Default value is 't'.

        Returns
        =======
        arbitrary_point : Point

        Raises
        ======
        ValueError
            When `parameter` already appears in the functions.

        See Also
        ========
        sympy.geometry.point.Point

        Examples
        ========
        >>> from sympy import Point, Ellipse
        >>> e1 = Ellipse(Point(0, 0), 3, 2)
        >>> e1.arbitrary_point()
        Point(3*cos(t), 2*sin(t))

        """
        t = _symbol(parameter)
        if t.name in (f.name for f in self.free_symbols):
            raise ValueError(
                'Symbol %s already appears in object and cannot be used as a parameter.'
                % t.name)
        return Point(self.center[0] + self.hradius * C.cos(t),
                     self.center[1] + self.vradius * C.sin(t))
Example #23
0
    def plot_interval(self, parameter='t'):
        """The plot interval for the default geometric plot of the Segment.

        Parameters
        ==========
        parameter : str, optional
            Default value is 't'.

        Returns
        =======
        plot_interval : list
            [parameter, lower_bound, upper_bound]

        Examples
        ========
        >>> from sympy import Point, Segment
        >>> p1, p2 = Point(0, 0), Point(5, 3)
        >>> s1 = Segment(p1, p2)
        >>> s1.plot_interval()
        [t, 0, 1]

        """
        t = _symbol(parameter)
        return [t, 0, 1]
Example #24
0
    def __new__(cls, *args, **kwargs):
        if kwargs.get('n', 0):
            n = kwargs.pop('n')
            args = list(args)
            # return a virtual polygon with n sides
            if len(args) == 2: # center, radius
                args.append(n)
            elif len(args) == 3: # center, radius, rotation
                args.insert(2, n)
            return RegularPolygon(*args, **kwargs)

        vertices = [Point(a) for a in args]

        # remove consecutive duplicates
        nodup = []
        for p in vertices:
            if nodup and p == nodup[-1]:
                continue
            nodup.append(p)
        if len(nodup) > 1 and nodup[-1] == nodup[0]:
            nodup.pop() # last point was same as first

        # remove collinear points unless they are shared points
        got = set()
        shared = set()
        for p in nodup:
            if p in got:
                shared.add(p)
            else:
                got.add(p)
        i = -3
        while i < len(nodup) - 3 and len(nodup) > 2:
            a, b, c = sorted([nodup[i], nodup[i + 1], nodup[i + 2]])
            if b not in shared and Point.is_collinear(a, b, c):
                nodup[i] = a
                nodup[i + 1] = None
                nodup.pop(i + 1)
            i += 1

        vertices = filter(lambda x: x is not None, nodup)

        if len(vertices) > 3:
            rv = GeometryEntity.__new__(cls, *vertices, **kwargs)
        elif len(vertices) == 3:
            return Triangle(*vertices, **kwargs)
        elif len(vertices) == 2:
            return Segment(*vertices, **kwargs)
        else:
            return Point(*vertices, **kwargs)

        # reject polygons that have intersecting sides unless the
        # intersection is a shared point or a generalized intersection.
        # A self-intersecting polygon is easier to detect than a
        # random set of segments since only those sides that are not
        # part of the convex hull can possibly intersect with other
        # sides of the polygon...but for now we use the n**2 algorithm
        # and check all sides with intersection with any preceding sides
        hit = _symbol('hit')
        if not rv.is_convex:
            sides = rv.sides
            for i, si in enumerate(sides):
                pts = si[0], si[1]
                ai = si.arbitrary_point(hit)
                for j in xrange(i):
                    sj = sides[j]
                    if sj[0] not in pts and sj[1] not in pts:
                        aj = si.arbitrary_point(hit)
                        tx = (solve(ai[0] - aj[0]) or [S.Zero])[0]
                        if tx.is_number and 0 <= tx <= 1:
                            ty = (solve(ai[1] - aj[1]) or [S.Zero])[0]
                            if (tx or ty) and ty.is_number and 0 <= ty <= 1:
                                print ai, aj
                                raise GeometryError("Polygon has intersecting sides.")

        return rv
Example #25
0
    def random_point(self, seed=None):
        """A random point on the ellipse.

        Returns
        =======

        point : Point

        See Also
        ========

        sympy.geometry.point.Point
        arbitrary_point : Returns parameterized point on ellipse

        Notes
        -----

        A random point may not appear to be on the ellipse, ie, `p in e` may
        return False. This is because the coordinates of the point will be
        floating point values, and when these values are substituted into the
        equation for the ellipse the result may not be zero because of floating
        point rounding error.

        Examples
        ========

        >>> from sympy import Point, Ellipse, Segment
        >>> e1 = Ellipse(Point(0, 0), 3, 2)
        >>> e1.random_point() # gives some random point
        Point(...)
        >>> p1 = e1.random_point(seed=0); p1.n(2)
        Point(2.1, 1.4)

        The random_point method assures that the point will test as being
        in the ellipse:

        >>> p1 in e1
        True

        Notes
        =====

        An arbitrary_point with a random value of t substituted into it may
        not test as being on the ellipse because the expression tested that
        a point is on the ellipse doesn't simplify to zero and doesn't evaluate
        exactly to zero:

        >>> from sympy.abc import t
        >>> e1.arbitrary_point(t)
        Point(3*cos(t), 2*sin(t))
        >>> p2 = _.subs(t, 0.1)
        >>> p2 in e1
        False

        Note that arbitrary_point routine does not take this approach. A value for
        cos(t) and sin(t) (not t) is substituted into the arbitrary point. There is
        a small chance that this will give a point that will not test as being
        in the ellipse, so the process is repeated (up to 10 times) until a
        valid point is obtained.

        """
        from sympy import sin, cos, Rational
        t = _symbol('t')
        x, y = self.arbitrary_point(t).args
        # get a random value in [-1, 1) corresponding to cos(t)
        # and confirm that it will test as being in the ellipse
        if seed is not None:
            rng = random.Random(seed)
        else:
            rng = random
        for i in range(10):  # should be enough?
            # simplify this now or else the Float will turn s into a Float
            c = 2*Rational(rng.random()) - 1
            s = sqrt(1 - c**2)
            p1 = Point(x.subs(cos(t), c), y.subs(sin(t), s))
            if p1 in self:
                return p1
        raise GeometryError(
            'Having problems generating a point in the ellipse.')
Example #26
0
    def random_point(self, seed=None):
        """A random point on the ellipse.

        Returns
        =======

        point : Point

        See Also
        ========

        sympy.geometry.point.Point
        arbitrary_point : Returns parameterized point on ellipse

        Notes
        -----

        A random point may not appear to be on the ellipse, ie, `p in e` may
        return False. This is because the coordinates of the point will be
        floating point values, and when these values are substituted into the
        equation for the ellipse the result may not be zero because of floating
        point rounding error.

        Examples
        ========

        >>> from sympy import Point, Ellipse, Segment
        >>> e1 = Ellipse(Point(0, 0), 3, 2)
        >>> e1.random_point() # gives some random point
        Point(...)
        >>> p1 = e1.random_point(seed=0); p1.n(2)
        Point(2.1, 1.4)

        The random_point method assures that the point will test as being
        in the ellipse:

        >>> p1 in e1
        True

        Notes
        =====

        An arbitrary_point with a random value of t substituted into it may
        not test as being on the ellipse because the expression tested that
        a point is on the ellipse doesn't simplify to zero and doesn't evaluate
        exactly to zero:

        >>> from sympy.abc import t
        >>> e1.arbitrary_point(t)
        Point(3*cos(t), 2*sin(t))
        >>> p2 = _.subs(t, 0.1)
        >>> p2 in e1
        False

        Note that arbitrary_point routine does not take this approach. A value for
        cos(t) and sin(t) (not t) is substituted into the arbitrary point. There is
        a small chance that this will give a point that will not test as being
        in the ellipse, so the process is repeated (up to 10 times) until a
        valid point is obtained.

        """
        from sympy import sin, cos, Rational
        t = _symbol('t')
        x, y = self.arbitrary_point(t).args
        # get a random value in [-1, 1) corresponding to cos(t)
        # and confirm that it will test as being in the ellipse
        if seed is not None:
            rng = random.Random(seed)
        else:
            rng = random
        for i in range(10):  # should be enough?
            # simplify this now or else the Float will turn s into a Float
            c = 2 * Rational(rng.random()) - 1
            s = sqrt(1 - c**2)
            p1 = Point(x.subs(cos(t), c), y.subs(sin(t), s))
            if p1 in self:
                return p1
        raise GeometryError(
            'Having problems generating a point in the ellipse.')
Example #27
0
    def __new__(cls, *args, **kwargs):
        if kwargs.get('n', 0):
            n = kwargs.pop('n')
            args = list(args)
            # return a virtual polygon with n sides
            if len(args) == 2:  # center, radius
                args.append(n)
            elif len(args) == 3:  # center, radius, rotation
                args.insert(2, n)
            return RegularPolygon(*args, **kwargs)

        vertices = [Point(a) for a in args]

        # remove consecutive duplicates
        nodup = []
        for p in vertices:
            if nodup and p == nodup[-1]:
                continue
            nodup.append(p)
        if len(nodup) > 1 and nodup[-1] == nodup[0]:
            nodup.pop()  # last point was same as first

        # remove collinear points unless they are shared points
        got = set()
        shared = set()
        for p in nodup:
            if p in got:
                shared.add(p)
            else:
                got.add(p)
        i = -3
        while i < len(nodup) - 3 and len(nodup) > 2:
            a, b, c = sorted([nodup[i], nodup[i + 1], nodup[i + 2]])
            if b not in shared and Point.is_collinear(a, b, c):
                nodup[i] = a
                nodup[i + 1] = None
                nodup.pop(i + 1)
            i += 1

        vertices = filter(lambda x: x is not None, nodup)

        if len(vertices) > 3:
            rv = GeometryEntity.__new__(cls, *vertices, **kwargs)
        elif len(vertices) == 3:
            return Triangle(*vertices, **kwargs)
        elif len(vertices) == 2:
            return Segment(*vertices, **kwargs)
        else:
            return Point(*vertices, **kwargs)

        # reject polygons that have intersecting sides unless the
        # intersection is a shared point or a generalized intersection.
        # A self-intersecting polygon is easier to detect than a
        # random set of segments since only those sides that are not
        # part of the convex hull can possibly intersect with other
        # sides of the polygon...but for now we use the n**2 algorithm
        # and check all sides with intersection with any preceding sides
        hit = _symbol('hit')
        if not rv.is_convex:
            sides = rv.sides
            for i, si in enumerate(sides):
                pts = si[0], si[1]
                ai = si.arbitrary_point(hit)
                for j in xrange(i):
                    sj = sides[j]
                    if sj[0] not in pts and sj[1] not in pts:
                        aj = si.arbitrary_point(hit)
                        tx = (solve(ai[0] - aj[0]) or [S.Zero])[0]
                        if tx.is_number and 0 <= tx <= 1:
                            ty = (solve(ai[1] - aj[1]) or [S.Zero])[0]
                            if (tx or ty) and ty.is_number and 0 <= ty <= 1:
                                print ai, aj
                                raise GeometryError(
                                    "Polygon has intersecting sides.")

        return rv
Example #28
0
File: line.py Project: Jerryy/sympy
    def arbitrary_point(self, parameter='t'):
        """A parameterized point on the Ray.

        Parameters
        ----------
        parameter : str, optional
            The name of the parameter which will be used for the parametric
            point. The default value is 't'.

        Returns
        -------
        point : Point

        Raises
        ------
        ValueError
            When `parameter` already appears in the Ray's definition.

        See Also
        --------
        Point

        Examples
        --------
         >>> from sympy import Ray, Point, Segment, S, simplify, solve
        >>> from sympy.abc import t
        >>> r = Ray(Point(0, 0), Point(2, 3))

        >>> p = r.arbitrary_point(t)

        The parameter `t` used in the arbitrary point maps 0 to the
        origin of the ray and 1 to the end of the ray at infinity
        (which will show up as NaN).

        >>> p.subs(t, 0), p.subs(t, 1)
        (Point(0, 0), Point(oo, oo))

        The unit that `t` moves you is based on the spacing of the
        points used to define the ray.

        >>> p.subs(t, 1/(S(1) + 1)) # one unit
        Point(2, 3)
        >>> p.subs(t, 2/(S(1) + 2)) # two units out
        Point(4, 6)
        >>> p.subs(t, S.Half/(S(1) + S.Half)) # half a unit out
        Point(1, 3/2)

        If you want to be located a distance of 1 from the origin of the
        ray, what value of `t` is needed?

        a) find the unit length and pick t accordingly
        >>> u = Segment(r[0], p.subs(t, S.Half)).length # S.Half = 1/(1 + 1)
        >>> want = 1
        >>> t_need = want/u
        >>> p_want = p.subs(t, t_need/(1 + t_need))
        >>> simplify(Segment(r[0], p_want).length)
        1

        b) find the t that makes the length from origin to p equal to 1
        >>> l = Segment(r[0], p).length
        >>> t_need = solve(l**2 - want**2, t) # use the square to remove abs() if it is there
        >>> t_need = [w for w in t_need if w.n() > 0][0] # take positive t
        >>> p_want = p.subs(t, t_need)
        >>> simplify(Segment(r[0], p_want).length)
        1

        """
        t = _symbol(parameter)
        if t.name in (f.name for f in self.free_symbols):
            raise ValueError(
                'Symbol %s already appears in object and cannot be used as a parameter.'
                % t.name)
        m = self.slope
        x = simplify(self.p1[0] + t / (1 - t) * (self.p2[0] - self.p1[0]))
        y = simplify(self.p1[1] + t / (1 - t) * (self.p2[1] - self.p1[1]))
        return Point(x, y)
Example #29
0
    def arbitrary_point(self, parameter='t'):
        """A parameterized point on the Ray.

        Parameters
        ==========

        parameter : str, optional
            The name of the parameter which will be used for the parametric
            point. The default value is 't'.

        Returns
        =======

        point : Point

        Raises
        ======

        ValueError
            When ``parameter`` already appears in the Ray's definition.

        See Also
        ========

        sympy.geometry.point.Point

        Examples
        ========

        >>> from sympy import Ray, Point, Segment, S, simplify, solve
        >>> from sympy.abc import t
        >>> r = Ray(Point(0, 0), Point(2, 3))

        >>> p = r.arbitrary_point(t)

        The parameter `t` used in the arbitrary point maps 0 to the
        origin of the ray and 1 to the end of the ray at infinity
        (which will show up as NaN).

        >>> p.subs(t, 0), p.subs(t, 1)
        (Point(0, 0), Point(oo, oo))

        The unit that `t` moves you is based on the spacing of the
        points used to define the ray.

        >>> p.subs(t, 1/(S(1) + 1)) # one unit
        Point(2, 3)
        >>> p.subs(t, 2/(S(1) + 2)) # two units out
        Point(4, 6)
        >>> p.subs(t, S.Half/(S(1) + S.Half)) # half a unit out
        Point(1, 3/2)

        If you want to be located a distance of 1 from the origin of the
        ray, what value of `t` is needed?

        a)  Find the unit length and pick `t` accordingly.

            >>> u = Segment(r.p1, p.subs(t, S.Half)).length # S.Half = 1/(1 + 1)
            >>> want = 1
            >>> t_need = want/u
            >>> p_want = p.subs(t, t_need/(1 + t_need))
            >>> simplify(Segment(r.p1, p_want).length)
            1

        b)  Find the `t` that makes the length from origin to `p` equal to 1.

            >>> l = Segment(r.p1, p).length
            >>> t_need = solve(l**2 - want**2, t) # use the square to remove abs() if it is there
            >>> t_need = [w for w in t_need if w.n() > 0][0] # take positive t
            >>> p_want = p.subs(t, t_need)
            >>> simplify(Segment(r.p1, p_want).length)
            1

        """
        t = _symbol(parameter)
        if t.name in (f.name for f in self.free_symbols):
            raise ValueError('Symbol %s already appears in object and cannot be used as a parameter.' % t.name)
        x = simplify(self.p1.x + t/(1 - t)*(self.p2.x - self.p1.x))
        y = simplify(self.p1.y + t/(1 - t)*(self.p2.y - self.p1.y))
        return Point(x, y)