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.')
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)
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))