Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
""" Arcs of circles and ellipses """ #***************************************************************************** # Copyright (C) 2010 Vincent Delecroix <20100.delecroix@gmail.com>, # # Distributed under the terms of the GNU General Public License (GPL) # # This code is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # The full text of the GPL is available at: # # http://www.gnu.org/licenses/ #***************************************************************************** from __future__ import print_function
from sage.plot.primitive import GraphicPrimitive from sage.plot.colors import to_mpl_color
from sage.plot.misc import options, rename_keyword
from math import fmod, sin, cos, pi, atan
class Arc(GraphicPrimitive): """ Primitive class for the Arc graphics type. See ``arc?`` for information about actually plotting an arc of a circle or an ellipse.
INPUT:
- ``x,y`` - coordinates of the center of the arc
- ``r1``, ``r2`` - lengths of the two radii
- ``angle`` - angle of the horizontal with width
- ``sector`` - sector of angle
- ``options`` - dict of valid plot options to pass to constructor
EXAMPLES:
Note that the construction should be done using ``arc``::
sage: from sage.plot.arc import Arc sage: print(Arc(0,0,1,1,pi/4,pi/4,pi/2,{})) Arc with center (0.0,0.0) radii (1.0,1.0) angle 0.785398163397 inside the sector (0.785398163397,1.57079632679) """ def __init__(self, x, y, r1, r2, angle, s1, s2, options): """ Initializes base class ``Arc``.
EXAMPLES::
sage: A = arc((2,3),1,1,pi/4,(0,pi)) sage: A[0].x == 2 True sage: A[0].y == 3 True sage: A[0].r1 == 1 True sage: A[0].r2 == 1 True sage: bool(A[0].angle == pi/4) True sage: bool(A[0].s1 == 0) True sage: bool(A[0].s2 == pi) True
TESTS::
sage: from sage.plot.arc import Arc sage: a = Arc(0,0,1,1,0,0,1,{}) sage: print(loads(dumps(a))) Arc with center (0.0,0.0) radii (1.0,1.0) angle 0.0 inside the sector (0.0,1.0) """ raise ValueError("the radii must be positive real numbers.")
def get_minmax_data(self): """ Returns a dictionary with the bounding box data.
The bounding box is computed as minimal as possible.
EXAMPLES:
An example without angle::
sage: p = arc((-2, 3), 1, 2) sage: d = p.get_minmax_data() sage: d['xmin'] -3.0 sage: d['xmax'] -1.0 sage: d['ymin'] 1.0 sage: d['ymax'] 5.0
The same example with a rotation of angle `\pi/2`::
sage: p = arc((-2, 3), 1, 2, pi/2) sage: d = p.get_minmax_data() sage: d['xmin'] -4.0 sage: d['xmax'] 0.0 sage: d['ymin'] 2.0 sage: d['ymax'] 4.0 """
s2 += twopi
angle += twopi
xmin = -r1 ymin = -r2 xmax = r1 ymax = r2 axmin = 0 axmax = pi aymin = pi / 2 aymax = 3 * pi / 2
xmin = -r2 ymin = -r1 xmax = r2 ymax = r1 axmin = 3 * pi / 2 axmax = pi / 2 aymin = 0 aymax = pi
else: r2 * sin_angle * sin(axmax)) xmax = -xmax axmax = fmod(axmax + pi, twopi)
aymax += twopi r2 * cos_angle * sin(aymax)) ymax = -ymax aymax = fmod(aymax + pi, twopi)
(x2 < x3 and x3 < x1) or (x3 < x1 and x1 < x2))
[self.y + ymin, self.y + ymax], dict=True)
def _allowed_options(self): """ Return the allowed options for the ``Arc`` class.
EXAMPLES::
sage: p = arc((3, 3), 1, 1) sage: p[0]._allowed_options()['alpha'] 'How transparent the figure is.' """ 'thickness': 'How thick the border of the arc is.', 'hue': 'The color given as a hue.', 'rgbcolor': 'The color', 'zorder': '2D only: The layer level in which to draw', 'linestyle': "2D only: The style of the line, which is one of " "'dashed', 'dotted', 'solid', 'dashdot', or '--', ':', '-', '-.', " "respectively."}
def _matplotlib_arc(self): """ Return ``self`` as a matplotlib arc object.
EXAMPLES::
sage: from sage.plot.arc import Arc sage: Arc(2,3,2.2,2.2,0,2,3,{})._matplotlib_arc() <matplotlib.patches.Arc object at ...> """ 2. * self.r1, 2. * self.r2, fmod(self.angle, 2 * pi) * (180. / pi), self.s1 * (180. / pi), self.s2 * (180. / pi))
def bezier_path(self): """ Return ``self`` as a Bezier path.
This is needed to concatenate arcs, in order to create hyperbolic polygons.
EXAMPLES::
sage: from sage.plot.arc import Arc sage: op = {'alpha':1,'thickness':1,'rgbcolor':'blue','zorder':0, ....: 'linestyle':'--'} sage: Arc(2,3,2.2,2.2,0,2,3,op).bezier_path() Graphics object consisting of 1 graphics primitive
sage: a = arc((0,0),2,1,0,(pi/5,pi/2+pi/12), linestyle="--", color="red") sage: b = a[0].bezier_path() sage: b[0] Bezier path from (1.133..., 0.8237...) to (-0.2655..., 0.9911...) """
def _repr_(self): """ String representation of ``Arc`` primitive.
EXAMPLES::
sage: from sage.plot.arc import Arc sage: print(Arc(2,3,2.2,2.2,0,2,3,{})) Arc with center (2.0,3.0) radii (2.2,2.2) angle 0.0 inside the sector (2.0,3.0) """
def _render_on_subplot(self, subplot): """ TESTS::
sage: A = arc((1,1),3,4,pi/4,(pi,4*pi/3)); A Graphics object consisting of 1 graphics primitive """
return_type='long'))
def plot3d(self): r""" TESTS::
sage: from sage.plot.arc import Arc sage: Arc(0,0,1,1,0,0,1,{}).plot3d() Traceback (most recent call last): ... NotImplementedError """
@rename_keyword(color='rgbcolor') @options(alpha=1, thickness=1, linestyle='solid', zorder=5, rgbcolor='blue', aspect_ratio=1.0) def arc(center, r1, r2=None, angle=0.0, sector=(0.0, 2 * pi), **options): r""" An arc (that is a portion of a circle or an ellipse)
Type ``arc.options`` to see all options.
INPUT:
- ``center`` - 2-tuple of real numbers - position of the center.
- ``r1``, ``r2`` - positive real numbers - radii of the ellipse. If only ``r1`` is set, then the two radii are supposed to be equal and this function returns an arc of circle.
- ``angle`` - real number - angle between the horizontal and the axis that corresponds to ``r1``.
- ``sector`` - 2-tuple (default: (0,2*pi))- angles sector in which the arc will be drawn.
OPTIONS:
- ``alpha`` - float (default: 1) - transparency
- ``thickness`` - float (default: 1) - thickness of the arc
- ``color``, ``rgbcolor`` - string or 2-tuple (default: 'blue') - the color of the arc
- ``linestyle`` - string (default: ``'solid'``) - The style of the line, which is one of ``'dashed'``, ``'dotted'``, ``'solid'``, ``'dashdot'``, or ``'--'``, ``':'``, ``'-'``, ``'-.'``, respectively.
EXAMPLES:
Plot an arc of circle centered at (0,0) with radius 1 in the sector `(\pi/4,3*\pi/4)`::
sage: arc((0,0), 1, sector=(pi/4,3*pi/4)) Graphics object consisting of 1 graphics primitive
Plot an arc of an ellipse between the angles 0 and `\pi/2`::
sage: arc((2,3), 2, 1, sector=(0,pi/2)) Graphics object consisting of 1 graphics primitive
Plot an arc of a rotated ellipse between the angles 0 and `\pi/2`::
sage: arc((2,3), 2, 1, angle=pi/5, sector=(0,pi/2)) Graphics object consisting of 1 graphics primitive
Plot an arc of an ellipse in red with a dashed linestyle::
sage: arc((0,0), 2, 1, 0, (0,pi/2), linestyle="dashed", color="red") Graphics object consisting of 1 graphics primitive sage: arc((0,0), 2, 1, 0, (0,pi/2), linestyle="--", color="red") Graphics object consisting of 1 graphics primitive
The default aspect ratio for arcs is 1.0::
sage: arc((0,0), 1, sector=(pi/4,3*pi/4)).aspect_ratio() 1.0
It is not possible to draw arcs in 3D::
sage: A = arc((0,0,0), 1) Traceback (most recent call last): ... NotImplementedError """
# Reset aspect_ratio to 'automatic' in case scale is 'semilog[xy]'. # Otherwise matplotlib complains. scale = scale[0] options['aspect_ratio'] = 'automatic'
raise ValueError("the sector must consist of two angles") center[0], center[1], r1, r2, angle, sector[0], sector[1], options)) |