Пример #1
0
    def sample_motion(self, N, numeric=True, start_margin=0, end_margin=0):
        r"""
        Return a sampling of the motion.

        TODO:

        Doc, examples
        """
        a, b = self._interval
        if numeric:
            if self._sampling_type == 'uniform':
                return [self.realization(RR(a + (i/Integer(N)) * (b-a)),  numeric=True) 
                        for i in range(start_margin, N+1-end_margin)]
            elif self._sampling_type == 'tan':
                return [self.realization(tan(RR(a + (i/Integer(N)) * (b-a))),  numeric=True) 
                        for i in range(start_margin, N+1-end_margin)]
            else:
                raise exceptions.NotImplementedError('Sampling ' + str(self._sampling_type) + ' is not supported.')
        else:
            if self._sampling_type == 'uniform':
                return [self.realization(a + (i/Integer(N)) * (b-a)) 
                        for i in range(start_margin, N+1-end_margin)]
            elif self._sampling_type == 'tan':
                return [self.realization(tan(a + (i/Integer(N)) * (b-a))) 
                        for i in range(start_margin, N+1-end_margin)]
            else:
                raise exceptions.NotImplementedError('Sampling ' + str(self._sampling_type) + ' is not supported.')
Пример #2
0
 def _sage_(self):
     import sage.all as sage
     return sage.tan(self.args[0]._sage_())
Пример #3
0
 def _sage_(self):
     import sage.all as sage
     return sage.tan(self.args[0]._sage_())
def visualPolarCoordinates(r, theta, xunit=1, yunit=1):
    """
    return the polar coordinated that you have to give
    in such a way the it *visually* appears `(r,theta)`
    when `xunit` and `yunit` are given.

    The input and output angles are in radian.

    INPUT:

    - ``r`` - the distance you want to see.

    - ``theta`` - the angle you want to see (radian or AngleMeasure).
                    If the angle is passed as 'AngleMeasure', the answer
                    will also be AngleMeasure

    - ``xunit`` - the dilatation factor in the `x` direction.

    - ``yunit`` - the dilatation factor in the `y` direction.

    OUTPUT:

    a tuple `(distance,angle)`

    EXAMPLES::

        sage: from yanntricks.SmallComputations import *
        sage: polar_with_dilatation(2,pi,2,1)
        (1, pi)
        sage: polar_with_dilatation(1,pi/4,2,2)
        (1/2, 1/4*pi)

    Notice the difference between::

        sage: polar_with_dilatation(1,pi/2,2,1/2)
        (2, 1/2*pi)

    and::

        sage: polar_with_dilatation(1,pi/2,2,0.5)
        (2.00000000000000, 1/2*pi)
    """
    from yanntricks.src.MathStructures import AngleMeasure

    arg_is_angle_measure = False
    orig_theta = theta
    if isinstance(theta, AngleMeasure):
        theta = numerical_approx(theta.radian)
        arg_is_angle_measure = True
    else:
        theta = numerical_approx(theta)

    if cos(theta) == 0:
        return (r / yunit, orig_theta)
    if cos(theta) == 1:
        return (r / xunit, orig_theta)
    if cos(theta) == -1:
        return (r / xunit, orig_theta)

    # For Sage, atan : R -> [-pi/2,pi/2]
    # thus one has to check the angle after having done atan( ... tan(...)  )
    # Here we assume that the deformed angle is next to the original one
    if xunit == yunit:
        alpha = theta
    else:
        alpha = atan((xunit / yunit) * tan(theta))
        if theta > pi / 2 and theta < 3 * pi / 2:
            alpha = alpha + pi

    rp = (r / xunit) * (cos(theta) / cos(alpha))

    if rp < 0:
        rp = -rp
        alpha = alpha + pi
    if arg_is_angle_measure:
        alpha = AngleMeasure(value_radian=alpha)
    return (rp, alpha)
Пример #5
0
    def _getOCvector(self,dimx,dimy,pspict=None):
        """
        Return a vector 
        O -> central point of the box
        such that the box of size (dimx,dimy) will not intersect the lines
        of the angle self.

          In fact we use this vector to translate from the mark_point 
          (not the center of the angle).
          Thus we are sure that the mark will in the same time
          - not intersect the lines
          - be further than the code.
        """

        #dprint(numerical_approx(self.angleA.degree))
        #dprint(numerical_approx(self.angleB.degree))

        if 0<self.angleA.degree < 90 and 0<self.angleB.degree < 90 :
            # In this case, the mark will be attached
            # - by the upper left to the line OB (let X be that point)
            # - by the lower right to the line OA   (let Y be that point)
            # We consider 'd', the diagonal of the mark that join OA to OB
            # The triangle OXY has angle 'alpha' at O and 'beta' at Y.
            # We consider the altitude 'h' of OXY from X.
            # Let 'sigma' be the angle made by the diagonal of the box.
            # beta = self.angleA + sigma
            # Using Pythagoras'theorem and some trigonometry,
            # we can determine all the lengths and angles.
            # The one we are interested in is OX. Trigonometry then 
            # provides the coordinates of X. 
            # Then the center of the mark's box is easy to compute 
            # as a translation by (dimx/2 , -dimy/2)

            d=sqrt(dimx**2+dimy**2)     # diagonal of the box
            sigma = arctan(dimy/dimx)
            beta = self.angleA.radian+sigma

            alpha=self.measure.radian

            h=d*sin(beta)
            l=h/sin(alpha)          # length OX

            # Here are the coordinates of X (with respect to O)
            x=l*cos(self.angleB.radian)
            y=l*sin(self.angleB.radian)

            # This is the vector O->central_point

            return AffineVector( self.O, Point( x+dimx/2,y-dimy/2) )   

        # In each case, the returned vector is the vector
        #  O -> center of the box containing the text.
        if 0<self.angleA.degree < 90 and ( self.angleB.degree==90 or self.angleB.radian==pi/2  ):
            y=dimx/tan(self.measure.radian)
            Q=self.O+(0,y)
            return AffineVector(self.O,Q+(dimx/2,dimy/2))

        if 0<self.angleA.degree < 90 and 90<self.angleB.degree < 180 :
            h=dimx*sin(self.angleA.radian)
            l=h/sin(self.measure.radian)
            gamma=pi-self.angleB.radian
            x=l*cos(gamma)
            y=l*sin(gamma)

            Q=self.O+(-x,y)     # lower left angle of the box
            return AffineVector(self.O, Q+(dimx/2,dimy/2) )

        if (self.angleA.radian==pi/2 or self.angleA.degree==90) and 90<self.angleB.degree<180 :
            l=dimx/tan(self.measure.radian)
            Q=self.O+(0,l)
            return AffineVector(self.O,Q+(-dimx/2,dimy/2))
            
        if 90<self.angleA.degree < 180 and 90<self.angleB.degree < 180 :
            
            d=sqrt(dimx**2+dimy**2)
            beta=pi-self.angleB.radian
            alpha=atan(dimy/dimx)
            gamma=alpha+beta
            sigma=pi-self.measure.radian-gamma
            h=d*sin(sigma)
            l=h/sin(self.measure.radian)
            x=l*cos(beta)
            y=l*sin(beta)
            Q=self.O+(-x,y)
            return AffineVector(self.O, Q+(dimx/2,dimy/2) )

        if 90<self.angleA.degree < 180 and (self.angleB.degree==180 or self.angleB.radian==pi) :
            l=dimy/sin(self.measure.radian)
            x=l*cos(self.measure.radian)
            y=dimy
            Q=self.O+(-x,y)
            return AffineVector( self.O, Q+(-dimx/2,-dimy/2) )


        if 90<self.angleA.degree < 180 and 180<self.angleB.degree < 270 :
            alpha=3*pi/2-self.angleB.radian
            h=dimy*sin(alpha)
            l=h/sin(self.measure.radian)
            gamma=self.angleA.radian-pi/2
            x=l*sin(gamma)
            y=l*cos(gamma)
            Q=self.O+(-x,y)
            return AffineVector(self.O,Q+(-dimx/2,-dimy/2))

        if (self.angleA.degree==180 or self.angleA.radian==pi) and  180<self.angleB.degree < 270:
            alpha=pi/2-self.measure.radian
            x=dimy*tan(alpha)
            Q=self.O+(-x,0)
            return AffineVector(self.O,Q+(-dimx/2,-dimy/2))

        if 180<self.angleA.degree < 270 and \
                    (self.angleB.degree==270 or self.angleB.radian==3*pi/2) :
            y=dimx/tan(self.measure.radian)
            Q=self.O+(0,-y)
            return AffineVector(self.O,Q+(-dimx/2,-dimy/2)  )

        if 270<self.angleA.degree < 360 and 0<self.angleB.degree<90:
            alpha=self.angleB.radian
            l=dimy*cos(alpha)
            beta=pi/2-alpha
            x=l*sin(beta)
            y=l*cos(beta)
            Q=self.O+(x,y)
            return AffineVector(self.O,Q+(dimx/2,-dimy/2))

        if (self.angleA.radian==3*pi/2 or self.angleA.degree==270) and \
                                            270<self.angleB.degree<360 :
            l=dimx/tan(self.measure.radian)
            x=0
            y=l
            Q=self.O+(x,-y)
            return AffineVector(self.O,Q+(dimx/2,-dimy/2))

        if 180<self.angleA.degree < 270 and 180<self.angleB.degree<270:
            d=sqrt(dimx**2+dimy**2)
            alpha=atan(dimy/dimx)
            beta=self.angleA.radian-pi
            gamma=alpha+beta
            h=d*sin(gamma)

            l=h/sin(self.measure.radian)
            sigma=3*pi/2-self.angleB.radian
            x=l*sin(sigma)
            y=l*cos(sigma)
            Q=self.O+(-x,-y)
            return AffineVector(self.O,Q+(-dimx/2,dimy/2))

        if 180<self.angleA.degree < 270 and 270<self.angleB.degree<360:
            alpha=pi/2-(self.angleA.radian-pi)
            beta=self.measure.radian-alpha
            h=dimx/(tan(alpha)+tan(beta))
            d1=h*tan(alpha)
            Q=self.O+(-d1,-h)

            return AffineVector( self.O,Q+(dimx/2,-dimy/2)  )
        if 270<self.angleA.degree < 360 and 270<self.angleB.degree<360:
            alpha=2*pi-self.angleA.radian
            beta=arctan(dimy/dimx)
            sigma=alpha+beta
            d=sqrt(dimx**2+dimy**2)
            h=d*sin(sigma)
            l=h/sin(self.measure.radian)
            gamma=self.angleA.radian-3*pi/2
            x=l*sin(gamma)
            y=l*cos(gamma)
            Q=self.O+(x,-y)
            return AffineVector(self.O,Q+(dimx/2,dimy/2))

        if 270<self.angleA.degree < 360 and (self.angleB.degree==360 or self.angleB.radian==2*pi or self.angleB.radian==0 or self.angleB.degree==0) :
            l=dimy/tan(self.measure.radian)
            Q=self.O+(l,0)
            return AffineVector(self.O,Q+(dimx/2,-dimy/2))

        if 260<self.angleA.degree < 360 and ( self.angleB.degree>360 or 0<self.angleB.degree<90):
            alpha=self.angleA.radian-pi/2
            h=dimy*sin(alpha)
            l=h/sin(self.measure.radian)
            beta=pi/2-self.angleB.radian
            x=l*sin(beta)
            y=l*cos(beta)
            Q=self.O+(x,y)
            return AffineVector(self.O,Q+(dimx/2,-dimy/2))

        # For the next few ones, the box touch the angles' vertex.
        # Thus we add a (0.1,0.1). If not, the mark touches the
        # arc circle.

        if 180 < self.angleA.degree < 270 and self.angleB.degree==0:
            Q=self.O+(0.1,-0.1)
            return AffineVector(self.O,Q+(dimx/2,-dimy/2))

        if 270 <= self.angleA.degree <= 360 and 90<=self.angleB.degree<=180 :
            Q=self.O+(0.1,0.1)
            return AffineVector(self.O,Q+(dimx/2,dimy/2))

        if (self.angleA.degree == 0 or self.angleA.radian== 0)  and 90 <= self.angleB.degree <= 180 :
            Q=self.O+(0.1,0.1)
            return AffineVector(self.O,Q+(dimx/2,dimy/2))

        if (self.angleA.degree == 180 or self.angleA.radian== pi)  and 270 <= self.angleB.degree <= 360 :
            Q=self.O+(-0.1,-0.1)
            return AffineVector(self.O,Q+(-dimx/2,-dimy/2))

        if 0 <= self.angleA.degree <= 90 and 180 <= self.angleB.degree <= 270 :
            Q=self.O+(-0.1,0.1)
            return AffineVector(self.O,Q+(-dimx/2,dimy/2))

        if self.angleA.degree == 0 or self.angleA.radian==0  :
            x=dimy/tan(self.measure.radian)
            K=self.O+(x+dimx/2,dimy/2)
            return AffineVector( self.O, K )


        raise ValueError("Not yet implemented for angles :",numerical_approx(self.angleA.degree),numerical_approx(self.angleB.degree))