def getNextRegularFunctionParameters(self,
                                         lmin,
                                         lmax,
                                         fun,
                                         df,
                                         xunit=1,
                                         yunit=1):
        """
        Return a value 'nl' of the parameter such that the integral of 'fun' from 'lmin' to 'nl' is 'df'.

        `lmax` - is the maximal value of the parameter. If the interval [lmin,lmax]  reveals to be too small, return 'None'

        """
        # Vcurve is the curve as visually seen taking the dilatation
        # into account.
        from yanntricks.src.Constructors import phyFunction
        from yanntricks.src.Constructors import ParametricCurve
        x = var('x')
        Vf1 = phyFunction(self.f1(xunit * x))
        Vf2 = phyFunction(self.f2(yunit * x))
        Vcurve = ParametricCurve(Vf1, Vf2)

        prop_precision = float(df) / 100  # precision of the interval
        if prop_precision == 0:
            raise ValueError("prop_precision is zero.")

        # We'll perform a dichotomy method.
        # 'too_large' is a value of the parameter we know to be too large
        # 'too_small' is a value of the parameter we know to be too small
        # 'ell' is the median value on which the condition is tested.
        # The dichotomy method consist to make 'too_large' or 'too_small' become 'ell' and to recalculate a new 'ell'

        too_small = lmin
        too_large = lmax
        if Vcurve.getFunctionIntegral(fun, too_small, too_large) < df:
            return None

        max_iter = 100
        done_iter = 0
        while done_iter < max_iter:
            ell = (too_large + too_small) / 2
            done_iter += 1
            integral = Vcurve.getFunctionIntegral(fun, lmin, ell)
            if abs(integral - df) < prop_precision:
                return ell
            if integral > df:
                too_large = ell
            if integral < df:
                too_small = ell
        raise ShouldNotHappenException("I give up with this dichotomy")
Esempio n. 2
0
    def reverse(self):
        """
        return the curve in the inverse sense but on the same interval

        EXAMPLE::

        sage: from yanntricks import *
        sage: x=var('x')
        sage: curve=ParametricCurve(cos(x),sin(x)).graph(0,2*pi).reverse()
        sage: print curve
        <The parametric curve given by
        x(t)=cos(2*pi - t)
        y(t)=sin(2*pi - t)
        between 0 and 2*pi>
        """
        from yanntricks.src.Constructors import ParametricCurve
        x = var('x')
        a = self.llamI
        b = self.llamF
        f1 = self.f1.sage(x=b - (x - a))
        f2 = self.f2.sage(x=b - (x - a))
        curve = ParametricCurve(f1, f2).graph(a, b)
        curve.f1.nul_function = self.f1.nul_function
        curve.f2.nul_function = self.f2.nul_function

        return curve
Esempio n. 3
0
 def visualParametricCurve(self, xunit, yunit):
     from yanntricks.src.Constructors import ParametricCurve
     from yanntricks.src.Constructors import phyFunction
     x = var('x')
     Vf1 = phyFunction(self.f1(xunit * x))
     Vf2 = phyFunction(self.f2(yunit * x))
     return ParametricCurve(Vf1, Vf2)
Esempio n. 4
0
    def parametric_curve(self):
        """
        Return the parametric curve corresponding to `self`.

        The starting point is `self.I` and the parameters
        is the arc length.
        The parameter is positive on the side of `self.B`
        and negative on the opposite side.

        EXAMPLES::

            sage: from yanntricks import *
            sage: segment=Segment(Point(0,0),Point(1,1))
            sage: curve=segment.parametric_curve()
            sage: print curve(0)
            <Point(0,0)>
            sage: print curve(1)
            <Point(1/2*sqrt(2),1/2*sqrt(2))>
            sage: print curve(segment.length)
            <Point(1,1)>
        """
        from yanntricks.src.Constructors import phyFunction
        from yanntricks.src.Constructors import ParametricCurve
        x = var('x')
        l = self.length
        f1 = phyFunction(self.I.x+x*(self.F.x-self.I.x)/l)
        f2 = phyFunction(self.I.y+x*(self.F.y-self.I.y)/l)
        return ParametricCurve(f1, f2, (0, l))
Esempio n. 5
0
    def rotate(self, theta):
        """
        Return a new ParametricCurve which graph is rotated by <theta> with respect to self.

        theta is given in degree.
        """
        from yanntricks.src.Constructors import ParametricCurve
        from yanntricks.src.radian_unit import radian
        alpha = radian(theta)
        g1 = cos(alpha) * self.f1 + sin(alpha) * self.f2
        g2 = -sin(alpha) * self.f1 + cos(alpha) * self.f2
        return ParametricCurve(g1, g2)
    def get_normal_vector(self, xx):
        """ 
        return a normalized normal vector to the graph of the function at xx

        The direction of the vector is outside

        INPUT:
        - ``x`` - a number, the position at which we want the normal vector

        OUTPUT:
        a vector

        EXAMPLES:
        sage: from yanntricks import *
        sage: x=var('x')
        sage: f=phyFunction(x**2)
        sage: print f.get_normal_vector(0)
        <vector I=<Point(0,0)> F=<Point(0,-1)>>
        """
        from yanntricks.src.Constructors import ParametricCurve
        x = var('x')
        F = ParametricCurve(x, self)
        return F.get_normal_vector(xx)
Esempio n. 7
0
    def parametric_curve(self, a=None, b=None):
        """
        Return the parametric curve associated to the circle.

        If optional arguments <a> and <b> are given, return the corresponding graph between the values a and b of the angle.

        The parameter of the curve is the angle in radian.
        """
        from yanntricks.src.Constructors import ParametricCurve
        from yanntricks.src.Constructors import phyFunction
        from yanntricks.src.Exceptions import MissingPictureException
        if self._parametric_curve is None:
            x = var('x')
            if self.visual is True:
                if self.pspict is None:
                    raise MissingPictureException(
                        "You are trying to draw something with 'visual==True' when not giving a pspict."
                    )
                f1 = phyFunction(self.center.x +
                                 self.radius * cos(x) / self.pspict.xunit)
                f2 = phyFunction(self.center.y +
                                 self.radius * sin(x) / self.pspict.yunit)
            else:
                f1 = phyFunction(self.center.x + self.radius * cos(x))
                f2 = phyFunction(self.center.y + self.radius * sin(x))
            try:
                ai = self.angleI.radian
                af = self.angleF.radian
            except AttributeError:
                ai = self.angleI
                af = self.angleF
            self._parametric_curve = ParametricCurve(f1, f2, (ai, af))
        curve = self._parametric_curve
        # The following is the typical line that is replaced by the decorator
        # 'copy_parameters'
        # curve.parameters=self.parameters.copy()
        if a == None:
            return curve
        else:
            return curve.graph(a, b)
    def parametric_curve(self):
        """
        return a parametric curve with the same graph as `self`.
        """
        from yanntricks.src.Constructors import phyFunction
        from yanntricks.src.Constructors import ParametricCurve
        if self._parametric_curve:
            return self._parametric_curve
        x = var('x')
        curve = ParametricCurve(phyFunction(x), self, (self.mx, self.Mx))
        curve.parameters = self.parameters.copy()

        curve.linear_plotpoints = self.linear_plotpoints
        curve.curvature_plotpoints = self.curvature_plotpoints
        curve.added_plotpoints = self.added_plotpoints

        curve._representativeParameters = self._representativeParameters
        self._parametric_curve = curve

        return curve
Esempio n. 9
0
    def derivative(self, n=1):
        """
        Return the parametric curve given by the derivative. (f1,f2) -> (f1',f2').

        INPUT:
        - ``n`` - an integer (default=1).  If the optional parameter `n` is given, give higher order derivatives. If n=0, return self.

        EXAMPLES::

            sage: from yanntricks import *
            sage: x=var('x')
            sage: f1=phyFunction(cos(2*x))
            sage: f2=phyFunction(x*exp(2*x))
            sage: F=ParametricCurve(f1,f2)
            sage: print F.derivative()
            <The parametric curve given by
            x(t)=-2*sin(2*t)
            y(t)=2*t*e^(2*t) + e^(2*t)
            between None and None>
            sage: print F.derivative(3)
            <The parametric curve given by
            x(t)=8*sin(2*t)
            y(t)=8*t*e^(2*t) + 12*e^(2*t)
            between None and None>
        """
        from yanntricks.src.Constructors import ParametricCurve
        try:
            return self._derivative_dict[n]
        except KeyError:
            pass
        if n == 1:
            self._derivative_dict[1] = ParametricCurve(self.f1.derivative(),
                                                       self.f2.derivative())
        else:
            self._derivative_dict[n] = self.derivative(n - 1).derivative()
        return self._derivative_dict[n]
Esempio n. 10
0
 def graph(self, mx, Mx):
     from yanntricks.src.Constructors import ParametricCurve
     gr = ParametricCurve(self.f1, self.f2, (mx, Mx))
     gr.parameters = self.parameters.copy()
     return gr