Basic objects such as Sphere, Box, Cone, etc. - 3D Graphics

Skip to content
Back to top
View this page
Edit this page

# Basic objects such as Sphere, Box, Cone, etc.

AUTHORS:

- Robert Bradshaw 2007-02: initial version

- Robert Bradshaw 2007-08: obj/tachyon rendering, much updating

- Robert Bradshaw 2007-08: cythonization

EXAMPLES:

Sage

    sage: from sage.plot.plot3d.shapes import *
    sage: S = Sphere(.5, color='yellow')
    sage: S += Cone(.5, .5, color='red').translate(0,0,.3)
    sage: S += Sphere(.1, color='white').translate(.45,-.1,.15)
    sage: S += Sphere(.05, color='black').translate(.51,-.1,.17)
    sage: S += Sphere(.1, color='white').translate(.45, .1,.15)
    sage: S += Sphere(.05, color='black').translate(.51, .1,.17)
    sage: S += Sphere(.1, color='yellow').translate(.5, 0, -.2)
    sage: S.show()
    sage: S.scale(1,1,2).show()

Python

    >>> from sage.all import *
    >>> from sage.plot.plot3d.shapes import *
    >>> S = Sphere(RealNumber('.5'), color='yellow')
    >>> S += Cone(RealNumber('.5'), RealNumber('.5'), color='red').translate(Integer(0),Integer(0),RealNumber('.3'))
    >>> S += Sphere(RealNumber('.1'), color='white').translate(RealNumber('.45'),-RealNumber('.1'),RealNumber('.15'))
    >>> S += Sphere(RealNumber('.05'), color='black').translate(RealNumber('.51'),-RealNumber('.1'),RealNumber('.17'))
    >>> S += Sphere(RealNumber('.1'), color='white').translate(RealNumber('.45'), RealNumber('.1'),RealNumber('.15'))
    >>> S += Sphere(RealNumber('.05'), color='black').translate(RealNumber('.51'), RealNumber('.1'),RealNumber('.17'))
    >>> S += Sphere(RealNumber('.1'), color='yellow').translate(RealNumber('.5'), Integer(0), -RealNumber('.2'))
    >>> S.show()
    >>> S.scale(Integer(1),Integer(1),Integer(2)).show()

Sage

    sage: from sage.plot.plot3d.shapes import *
    sage: Torus(.7, .2, color=(0,.3,0)).show()

[Python]

    >>> from sage.all import *
    >>> from sage.plot.plot3d.shapes import *
    >>> Torus(RealNumber('.7'), RealNumber('.2'), color=(Integer(0),RealNumber('.3'),Integer(0))).show()

class sage.plot.plot3d.shapes.Box(*size, **kwds)

  Bases: `IndexFaceSet`

  Return a box.

  EXAMPLES:

  Sage

      sage: from sage.plot.plot3d.shapes import Box

  Python

      >>> from sage.all import *
      >>> from sage.plot.plot3d.shapes import Box

  A square black box:

  Sage

      sage: show(Box([1,1,1]), color='black')

  [Python]

      >>> from sage.all import *
      >>> show(Box([Integer(1),Integer(1),Integer(1)]), color='black')

  A red rectangular box:

  Sage

      sage: show(Box([2,3,4], color='red'))

  Python

      >>> from sage.all import *
      >>> show(Box([Integer(2),Integer(3),Integer(4)], color='red'))

  A stack of boxes:

  Sage

      sage: show(sum(Box([2,3,1], color='red').translate((0,0,6*i))
      ....:          for i in [0..3]))

  [Python]

      >>> from sage.all import *
      >>> show(sum(Box([Integer(2),Integer(3),Integer(1)], color='red').translate((Integer(0),Integer(0),Integer(6)*i))
      ...          for i in (ellipsis_range(Integer(0),Ellipsis,Integer(3)))))

  A sinusoidal stack of multicolored boxes:

  Sage

      sage: B = sum(Box([2,4,1/4],                                                    # needs sage.symbolic
      ....:             color=(i/4,i/5,1)).translate((sin(i),0,5-i))
      ....:         for i in [0..20])
      sage: show(B, figsize=6)                                                        # needs sage.symbolic

  Python

      >>> from sage.all import *
      >>> B = sum(Box([Integer(2),Integer(4),Integer(1)/Integer(4)],                                                    # needs sage.symbolic
      ...             color=(i/Integer(4),i/Integer(5),Integer(1))).translate((sin(i),Integer(0),Integer(5)-i))
      ...         for i in (ellipsis_range(Integer(0),Ellipsis,Integer(20))))
      >>> show(B, figsize=Integer(6))                                                        # needs sage.symbolic

  bounding_box()

    EXAMPLES:

    Sage

        sage: from sage.plot.plot3d.shapes import Box
        sage: Box([1,2,3]).bounding_box()
        ((-1.0, -2.0, -3.0), (1.0, 2.0, 3.0))

    Python

        >>> from sage.all import *
        >>> from sage.plot.plot3d.shapes import Box
        >>> Box([Integer(1),Integer(2),Integer(3)]).bounding_box()
        ((-1.0, -2.0, -3.0), (1.0, 2.0, 3.0))

  x3d_geometry()

    EXAMPLES:

    Sage

        sage: from sage.plot.plot3d.shapes import Box
        sage: Box([1,2,1/4]).x3d_geometry()
        "<Box size='1.0 2.0 0.25'/>"

    Python

        >>> from sage.all import *
        >>> from sage.plot.plot3d.shapes import Box
        >>> Box([Integer(1),Integer(2),Integer(1)/Integer(4)]).x3d_geometry()
        "<Box size='1.0 2.0 0.25'/>"

sage.plot.plot3d.shapes.ColorCube(size, colors, opacity=1, **kwds)

  Return a cube with given size and sides with given colors.

  INPUT:

  - `size` – 3-tuple of sizes (same as for box and frame)

  - `colors` – list of either 3 or 6 colors

  - `opacity` – (default: 1) opacity of cube sides

  - `**kwds` – passed to the face constructor

  OUTPUT: a 3d graphics object

  EXAMPLES:

  A color cube with translucent sides:

  Sage

      sage: from sage.plot.plot3d.shapes import ColorCube
      sage: c = ColorCube([1,2,3], ['red', 'blue', 'green', 'black', 'white', 'orange'], opacity=0.5)
      sage: c.show()

  Python

      >>> from sage.all import *
      >>> from sage.plot.plot3d.shapes import ColorCube
      >>> c = ColorCube([Integer(1),Integer(2),Integer(3)], ['red', 'blue', 'green', 'black', 'white', 'orange'], opacity=RealNumber('0.5'))
      >>> c.show()

  Sage

      sage: list(c.texture_set())[0].opacity
      0.5

  [Python]

      >>> from sage.all import *
      >>> list(c.texture_set())[Integer(0)].opacity
      0.5

  If you omit the last 3 colors then the first three are repeated (with repeated colors on opposing faces):

  Sage

      sage: c = ColorCube([0.5,0.5,0.5], ['red', 'blue', 'green'])

  Python

      >>> from sage.all import *
      >>> c = ColorCube([RealNumber('0.5'),RealNumber('0.5'),RealNumber('0.5')], ['red', 'blue', 'green'])

class sage.plot.plot3d.shapes.Cone

  Bases: `ParametricSurface`

  A cone, with base in the xy-plane pointing up the z-axis.

  INPUT:

  - `radius` – positive real number

  - `height` – positive real number

  - `closed` – whether or not to include the base (default: `True`)

  - `**kwds` – passed to the ParametricSurface constructor

  EXAMPLES:

  Sage

      sage: from sage.plot.plot3d.shapes import Cone
      sage: c = Cone(3/2, 1, color='red')
      sage: c += Cone(1, 2, color='yellow').translate(3, 0, 0)
      sage: c.show(aspect_ratio=1)

  Python

      >>> from sage.all import *
      >>> from sage.plot.plot3d.shapes import Cone
      >>> c = Cone(Integer(3)/Integer(2), Integer(1), color='red')
      >>> c += Cone(Integer(1), Integer(2), color='yellow').translate(Integer(3), Integer(0), Integer(0))
      >>> c.show(aspect_ratio=Integer(1))

  We may omit the base:

  Sage

      sage: Cone(1, 1, closed=False)
      Graphics3d Object

  [Python]

      >>> from sage.all import *
      >>> Cone(Integer(1), Integer(1), closed=False)
      Graphics3d Object

  A spiky plot of the sine function:

  Sage

      sage: sum(Cone(.1, sin(n), color='yellow').translate(n, sin(n), 0)              # needs sage.symbolic
      ....:     for n in [0..10, step=.1])
      Graphics3d Object

  Python

      >>> from sage.all import *
      >>> sum(Cone(RealNumber('.1'), sin(n), color='yellow').translate(n, sin(n), Integer(0))              # needs sage.symbolic
      ...     for n in (ellipsis_range(Integer(0),Ellipsis,Integer(10), step=RealNumber('.1'))))
      Graphics3d Object

  A Christmas tree:

  Sage

      sage: T = sum(Cone(exp(-n/5), 4/3*exp(-n/5),                                    # needs sage.symbolic
      ....:              color=(0, .5, 0)).translate(0, 0, -3*exp(-n/5))
      ....:         for n in [1..7])
      sage: T += Cone(1/8, 1, color='brown').translate(0, 0, -3)                      # needs sage.symbolic
      sage: T.show(aspect_ratio=1, frame=False)                                       # needs sage.symbolic

  [Python]

      >>> from sage.all import *
      >>> T = sum(Cone(exp(-n/Integer(5)), Integer(4)/Integer(3)*exp(-n/Integer(5)),                                    # needs sage.symbolic
      ...              color=(Integer(0), RealNumber('.5'), Integer(0))).translate(Integer(0), Integer(0), -Integer(3)*exp(-n/Integer(5)))
      ...         for n in (ellipsis_range(Integer(1),Ellipsis,Integer(7))))
      >>> T += Cone(Integer(1)/Integer(8), Integer(1), color='brown').translate(Integer(0), Integer(0), -Integer(3))                      # needs sage.symbolic
      >>> T.show(aspect_ratio=Integer(1), frame=False)                                       # needs sage.symbolic

  get_grid(ds)

    Return the grid on which to evaluate this parametric surface.

    EXAMPLES:

    Sage

        sage: from sage.plot.plot3d.shapes import Cone
        sage: Cone(1, 3, closed=True).get_grid(100)
        ([1, 0, -1], [0.0, 1.2566..., 2.5132..., 3.7699..., 5.0265..., 0.0])
        sage: Cone(1, 3, closed=False).get_grid(100)
        ([1, 0], [0.0, 1.2566..., 2.5132..., 3.7699..., 5.0265..., 0.0])
        sage: len(Cone(1, 3).get_grid(.001)[1])
        38

    Python

        >>> from sage.all import *
        >>> from sage.plot.plot3d.shapes import Cone
        >>> Cone(Integer(1), Integer(3), closed=True).get_grid(Integer(100))
        ([1, 0, -1], [0.0, 1.2566..., 2.5132..., 3.7699..., 5.0265..., 0.0])
        >>> Cone(Integer(1), Integer(3), closed=False).get_grid(Integer(100))
        ([1, 0], [0.0, 1.2566..., 2.5132..., 3.7699..., 5.0265..., 0.0])
        >>> len(Cone(Integer(1), Integer(3)).get_grid(RealNumber('.001'))[Integer(1)])
        38

  x3d_geometry()

    EXAMPLES:

    Sage

        sage: from sage.plot.plot3d.shapes import Cone
        sage: Cone(1, 3).x3d_geometry()
        "<Cone bottomRadius='1.0' height='3.0'/>"

    Python

        >>> from sage.all import *
        >>> from sage.plot.plot3d.shapes import Cone
        >>> Cone(Integer(1), Integer(3)).x3d_geometry()
        "<Cone bottomRadius='1.0' height='3.0'/>"

class sage.plot.plot3d.shapes.Cylinder

  Bases: `ParametricSurface`

  A cone, with base in the xy-plane pointing up the z-axis.

  INPUT:

  - `radius` – positive real number

  - `height` – positive real number

  - `closed` – whether or not to include the ends (default: `True`)

  - `**kwds` – passed to the `ParametricSurface` constructor

  EXAMPLES:

  Sage

      sage: from sage.plot.plot3d.shapes import Cylinder
      sage: c = Cylinder(3/2, 1, color='red')
      sage: c += Cylinder(1, 2, color='yellow').translate(3, 0, 0)
      sage: c.show(aspect_ratio=1)

  Python

      >>> from sage.all import *
      >>> from sage.plot.plot3d.shapes import Cylinder
      >>> c = Cylinder(Integer(3)/Integer(2), Integer(1), color='red')
      >>> c += Cylinder(Integer(1), Integer(2), color='yellow').translate(Integer(3), Integer(0), Integer(0))
      >>> c.show(aspect_ratio=Integer(1))

  We may omit the base:

  Sage

      sage: Cylinder(1, 1, closed=False)
      Graphics3d Object

  [Python]

      >>> from sage.all import *
      >>> Cylinder(Integer(1), Integer(1), closed=False)
      Graphics3d Object

  Some gears:

  Sage

      sage: # needs sage.symbolic
      sage: G = Cylinder(1, .5) + Cylinder(.25, 3).translate(0, 0, -3)
      sage: G += sum(Cylinder(.2, 1).translate(cos(2*pi*n/9), sin(2*pi*n/9), 0)
      ....:          for n in [1..9])
      sage: G += G.translate(2.3, 0, -.5)
      sage: G += G.translate(3.5, 2, -1)
      sage: G.show(aspect_ratio=1, frame=False)

  Python

      >>> from sage.all import *
      >>> # needs sage.symbolic
      >>> G = Cylinder(Integer(1), RealNumber('.5')) + Cylinder(RealNumber('.25'), Integer(3)).translate(Integer(0), Integer(0), -Integer(3))
      >>> G += sum(Cylinder(RealNumber('.2'), Integer(1)).translate(cos(Integer(2)*pi*n/Integer(9)), sin(Integer(2)*pi*n/Integer(9)), Integer(0))
      ...          for n in (ellipsis_range(Integer(1),Ellipsis,Integer(9))))
      >>> G += G.translate(RealNumber('2.3'), Integer(0), -RealNumber('.5'))
      >>> G += G.translate(RealNumber('3.5'), Integer(2), -Integer(1))
      >>> G.show(aspect_ratio=Integer(1), frame=False)

  bounding_box()

    EXAMPLES:

    Sage

        sage: from sage.plot.plot3d.shapes import Cylinder
        sage: Cylinder(1, 2).bounding_box()
        ((-1.0, -1.0, 0), (1.0, 1.0, 2.0))

    Python

        >>> from sage.all import *
        >>> from sage.plot.plot3d.shapes import Cylinder
        >>> Cylinder(Integer(1), Integer(2)).bounding_box()
        ((-1.0, -1.0, 0), (1.0, 1.0, 2.0))

  get_endpoints(transform=None)

    EXAMPLES:

    Sage

        sage: from sage.plot.plot3d.shapes import Cylinder
        sage: from sage.plot.plot3d.transform import Transformation
        sage: Cylinder(1, 5).get_endpoints()
        ((0, 0, 0), (0, 0, 5.0))
        sage: Cylinder(1, 5).get_endpoints(Transformation(trans=(1,2,3),
        ....:                                             scale=(2,2,2)))
        ((1.0, 2.0, 3.0), (1.0, 2.0, 13.0))

    Python

        >>> from sage.all import *
        >>> from sage.plot.plot3d.shapes import Cylinder
        >>> from sage.plot.plot3d.transform import Transformation
        >>> Cylinder(Integer(1), Integer(5)).get_endpoints()
        ((0, 0, 0), (0, 0, 5.0))
        >>> Cylinder(Integer(1), Integer(5)).get_endpoints(Transformation(trans=(Integer(1),Integer(2),Integer(3)),
        ...                                             scale=(Integer(2),Integer(2),Integer(2))))
        ((1.0, 2.0, 3.0), (1.0, 2.0, 13.0))

  get_grid(ds)

    Return the grid on which to evaluate this parametric surface.

    EXAMPLES:

    Sage

        sage: from sage.plot.plot3d.shapes import Cylinder
        sage: Cylinder(1, 3, closed=True).get_grid(100)
        ([2, 1, -1, -2], [0.0, 1.2566..., 2.5132..., 3.7699..., 5.0265..., 0.0])
        sage: Cylinder(1, 3, closed=False).get_grid(100)
        ([1, -1], [0.0, 1.2566..., 2.5132..., 3.7699..., 5.0265..., 0.0])
        sage: len(Cylinder(1, 3).get_grid(.001)[1])
        38

    Python

        >>> from sage.all import *
        >>> from sage.plot.plot3d.shapes import Cylinder
        >>> Cylinder(Integer(1), Integer(3), closed=True).get_grid(Integer(100))
        ([2, 1, -1, -2], [0.0, 1.2566..., 2.5132..., 3.7699..., 5.0265..., 0.0])
        >>> Cylinder(Integer(1), Integer(3), closed=False).get_grid(Integer(100))
        ([1, -1], [0.0, 1.2566..., 2.5132..., 3.7699..., 5.0265..., 0.0])
        >>> len(Cylinder(Integer(1), Integer(3)).get_grid(RealNumber('.001'))[Integer(1)])
        38

  get_radius(transform=None)

    EXAMPLES:

    Sage

        sage: from sage.plot.plot3d.shapes import Cylinder
        sage: from sage.plot.plot3d.transform import Transformation
        sage: Cylinder(3, 1).get_radius()
        3.0
        sage: Cylinder(3, 1).get_radius(Transformation(trans=(1,2,3),
        ....:                                          scale=(2,2,2)))
        6.0

    Python

        >>> from sage.all import *
        >>> from sage.plot.plot3d.shapes import Cylinder
        >>> from sage.plot.plot3d.transform import Transformation
        >>> Cylinder(Integer(3), Integer(1)).get_radius()
        3.0
        >>> Cylinder(Integer(3), Integer(1)).get_radius(Transformation(trans=(Integer(1),Integer(2),Integer(3)),
        ...                                          scale=(Integer(2),Integer(2),Integer(2))))
        6.0

  jmol_repr(render_params)

    EXAMPLES:

    Sage

        sage: from sage.plot.plot3d.shapes import Cylinder

    Python

        >>> from sage.all import *
        >>> from sage.plot.plot3d.shapes import Cylinder

    For thin cylinders, lines are used:

    Sage

        sage: C = Cylinder(.1, 4)
        sage: C.jmol_repr(C.default_render_params())
        ['\ndraw line_1 width 0.1 {0 0 0} {0 0 4.0}\ncolor $line_1  [102,102,255]\n']

    [Python]

        >>> from sage.all import *
        >>> C = Cylinder(RealNumber('.1'), Integer(4))
        >>> C.jmol_repr(C.default_render_params())
        ['\ndraw line_1 width 0.1 {0 0 0} {0 0 4.0}\ncolor $line_1  [102,102,255]\n']

    For anything larger, we use a pmesh:

    Sage

        sage: C = Cylinder(3, 1, closed=False)
        sage: C.jmol_repr(C.testing_render_params())
        ['pmesh obj_1 "obj_1.pmesh"\ncolor pmesh  [102,102,255]']

    Python

        >>> from sage.all import *
        >>> C = Cylinder(Integer(3), Integer(1), closed=False)
        >>> C.jmol_repr(C.testing_render_params())
        ['pmesh obj_1 "obj_1.pmesh"\ncolor pmesh  [102,102,255]']

  tachyon_repr(render_params)

    EXAMPLES:

    Sage

        sage: from sage.plot.plot3d.shapes import Cylinder
        sage: C = Cylinder(1/2, 4, closed=False)
        sage: C.tachyon_repr(C.default_render_params())
        'FCylinder\n   Base 0 0 0\n   Apex 0 0 4.0\n   Rad 0.5\n   texture...     '
        sage: C = Cylinder(1, 2)
        sage: C.tachyon_repr(C.default_render_params())
            ['Ring Center 0 0 0 Normal 0 0 1 Inner 0 Outer 1.0 texture...',
             'FCylinder\n   Base 0 0 0\n   Apex 0 0 2.0\n   Rad 1.0\n   texture...     ',
             'Ring Center 0 0 2.0 Normal 0 0 1 Inner 0 Outer 1.0 texture...']

    Python

        >>> from sage.all import *
        >>> from sage.plot.plot3d.shapes import Cylinder
        >>> C = Cylinder(Integer(1)/Integer(2), Integer(4), closed=False)
        >>> C.tachyon_repr(C.default_render_params())
        'FCylinder\n   Base 0 0 0\n   Apex 0 0 4.0\n   Rad 0.5\n   texture...     '
        >>> C = Cylinder(Integer(1), Integer(2))
        >>> C.tachyon_repr(C.default_render_params())
            ['Ring Center 0 0 0 Normal 0 0 1 Inner 0 Outer 1.0 texture...',
             'FCylinder\n   Base 0 0 0\n   Apex 0 0 2.0\n   Rad 1.0\n   texture...     ',
             'Ring Center 0 0 2.0 Normal 0 0 1 Inner 0 Outer 1.0 texture...']

  x3d_geometry()

    EXAMPLES:

    Sage

        sage: from sage.plot.plot3d.shapes import Cylinder
        sage: Cylinder(1, 2).x3d_geometry()
        "<Cylinder radius='1.0' height='2.0'/>"

    Python

        >>> from sage.all import *
        >>> from sage.plot.plot3d.shapes import Cylinder
        >>> Cylinder(Integer(1), Integer(2)).x3d_geometry()
        "<Cylinder radius='1.0' height='2.0'/>"

sage.plot.plot3d.shapes.LineSegment(start, end, thickness=1, radius=None, **kwds)

  Create a line segment, which is drawn as a cylinder from start to end with radius `radius`.

  EXAMPLES:

  Sage

      sage: from sage.plot.plot3d.shapes import LineSegment, Sphere
      sage: P = (0,0,0.1)
      sage: Q = (0.5,0.6,0.7)
      sage: S = Sphere(.2, color='red').translate(P)
      sage: S += Sphere(.2, color='blue').translate(Q)
      sage: S += LineSegment(P, Q, .05, color='black')
      sage: S.show()

  Python

      >>> from sage.all import *
      >>> from sage.plot.plot3d.shapes import LineSegment, Sphere
      >>> P = (Integer(0),Integer(0),RealNumber('0.1'))
      >>> Q = (RealNumber('0.5'),RealNumber('0.6'),RealNumber('0.7'))
      >>> S = Sphere(RealNumber('.2'), color='red').translate(P)
      >>> S += Sphere(RealNumber('.2'), color='blue').translate(Q)
      >>> S += LineSegment(P, Q, RealNumber('.05'), color='black')
      >>> S.show()

  Sage

      sage: S = Sphere(.1, color='red').translate(P)
      sage: S += Sphere(.1, color='blue').translate(Q)
      sage: S += LineSegment(P, Q, .15, color='black')
      sage: S.show()

  [Python]

      >>> from sage.all import *
      >>> S = Sphere(RealNumber('.1'), color='red').translate(P)
      >>> S += Sphere(RealNumber('.1'), color='blue').translate(Q)
      >>> S += LineSegment(P, Q, RealNumber('.15'), color='black')
      >>> S.show()

  AUTHOR:

  - Robert Bradshaw

class sage.plot.plot3d.shapes.Sphere

  Bases: `ParametricSurface`

  This class represents a sphere centered at the origin.

  EXAMPLES:

  Sage

      sage: from sage.plot.plot3d.shapes import Sphere
      sage: Sphere(3)
      Graphics3d Object

  Python

      >>> from sage.all import *
      >>> from sage.plot.plot3d.shapes import Sphere
      >>> Sphere(Integer(3))
      Graphics3d Object

  Plot with `aspect_ratio=1` to see it unsquashed:

  Sage

      sage: S = Sphere(3, color='blue') + Sphere(2, color='red').translate(0,3,0)
      sage: S.show(aspect_ratio=1)

  [Python]

      >>> from sage.all import *
      >>> S = Sphere(Integer(3), color='blue') + Sphere(Integer(2), color='red').translate(Integer(0),Integer(3),Integer(0))
      >>> S.show(aspect_ratio=Integer(1))

  Scale to get an ellipsoid:

  Sage

      sage: S = Sphere(1).scale(1,2,1/2)
      sage: S.show(aspect_ratio=1)

  Python

      >>> from sage.all import *
      >>> S = Sphere(Integer(1)).scale(Integer(1),Integer(2),Integer(1)/Integer(2))
      >>> S.show(aspect_ratio=Integer(1))

  bounding_box()

    Return the bounding box that contains this sphere.

    EXAMPLES:

    Sage

        sage: from sage.plot.plot3d.shapes import Sphere
        sage: Sphere(3).bounding_box()
        ((-3.0, -3.0, -3.0), (3.0, 3.0, 3.0))

    Python

        >>> from sage.all import *
        >>> from sage.plot.plot3d.shapes import Sphere
        >>> Sphere(Integer(3)).bounding_box()
        ((-3.0, -3.0, -3.0), (3.0, 3.0, 3.0))

  get_grid(ds)

    Return the range of variables to be evaluated on to render as a parametric surface.

    EXAMPLES:

    Sage

        sage: from sage.plot.plot3d.shapes import Sphere
        sage: Sphere(1).get_grid(100)
        ([-10.0, ..., 10.0],
         [0.0, ..., 3.141592653589793, ..., 0.0])

    Python

        >>> from sage.all import *
        >>> from sage.plot.plot3d.shapes import Sphere
        >>> Sphere(Integer(1)).get_grid(Integer(100))
        ([-10.0, ..., 10.0],
         [0.0, ..., 3.141592653589793, ..., 0.0])

  jmol_repr(render_params)

    EXAMPLES:

    Sage

        sage: from sage.plot.plot3d.shapes import Sphere

    Python

        >>> from sage.all import *
        >>> from sage.plot.plot3d.shapes import Sphere

    Jmol has native code for handling spheres:

    Sage

        sage: S = Sphere(2)
        sage: S.jmol_repr(S.default_render_params())
        ['isosurface sphere_1  center {0 0 0} sphere 2.0\ncolor isosurface  [102,102,255]']
        sage: S.translate(10, 100, 1000).jmol_repr(S.default_render_params())
        [['isosurface sphere_1  center {10.0 100.0 1000.0} sphere 2.0\ncolor isosurface  [102,102,255]']]

    [Python]

        >>> from sage.all import *
        >>> S = Sphere(Integer(2))
        >>> S.jmol_repr(S.default_render_params())
        ['isosurface sphere_1  center {0 0 0} sphere 2.0\ncolor isosurface  [102,102,255]']
        >>> S.translate(Integer(10), Integer(100), Integer(1000)).jmol_repr(S.default_render_params())
        [['isosurface sphere_1  center {10.0 100.0 1000.0} sphere 2.0\ncolor isosurface  [102,102,255]']]

    It cannot natively handle ellipsoids:

    Sage

        sage: Sphere(1).scale(2, 3, 4).jmol_repr(S.testing_render_params())
        [['pmesh obj_2 "obj_2.pmesh"\ncolor pmesh  [102,102,255]']]

    Python

        >>> from sage.all import *
        >>> Sphere(Integer(1)).scale(Integer(2), Integer(3), Integer(4)).jmol_repr(S.testing_render_params())
        [['pmesh obj_2 "obj_2.pmesh"\ncolor pmesh  [102,102,255]']]

    Small spheres need extra hints to render well:

    Sage

        sage: Sphere(.01).jmol_repr(S.default_render_params())
        ['isosurface sphere_1 resolution 100 center {0 0 0} sphere 0.01\ncolor isosurface  [102,102,255]']

    [Python]

        >>> from sage.all import *
        >>> Sphere(RealNumber('.01')).jmol_repr(S.default_render_params())
        ['isosurface sphere_1 resolution 100 center {0 0 0} sphere 0.01\ncolor isosurface  [102,102,255]']

  tachyon_repr(render_params)

    Tachyon can natively handle spheres. Ellipsoids rendering is done as a parametric surface.

    EXAMPLES:

    Sage

        sage: from sage.plot.plot3d.shapes import Sphere
        sage: S = Sphere(2)
        sage: S.tachyon_repr(S.default_render_params())
        'Sphere center 0 0 0 Rad 2.0 texture...'
        sage: S.translate(1, 2, 3).scale(3).tachyon_repr(S.default_render_params())
        [['Sphere center 3.0 6.0 9.0 Rad 6.0 texture...']]
        sage: S.scale(1,1/2,1/4).tachyon_repr(S.default_render_params())
        [['TRI V0 0 0 -0.5 V1 0.308116 0.0271646 -0.493844 V2 0.312869 0 -0.493844',
          'texture...',
           ...
          'TRI V0 0.308116 -0.0271646 0.493844 V1 0.312869 0 0.493844 V2 0 0 0.5',
          'texture...']]

    Python

        >>> from sage.all import *
        >>> from sage.plot.plot3d.shapes import Sphere
        >>> S = Sphere(Integer(2))
        >>> S.tachyon_repr(S.default_render_params())
        'Sphere center 0 0 0 Rad 2.0 texture...'
        >>> S.translate(Integer(1), Integer(2), Integer(3)).scale(Integer(3)).tachyon_repr(S.default_render_params())
        [['Sphere center 3.0 6.0 9.0 Rad 6.0 texture...']]
        >>> S.scale(Integer(1),Integer(1)/Integer(2),Integer(1)/Integer(4)).tachyon_repr(S.default_render_params())
        [['TRI V0 0 0 -0.5 V1 0.308116 0.0271646 -0.493844 V2 0.312869 0 -0.493844',
          'texture...',
           ...
          'TRI V0 0.308116 -0.0271646 0.493844 V1 0.312869 0 0.493844 V2 0 0 0.5',
          'texture...']]

  x3d_geometry()

    EXAMPLES:

    Sage

        sage: from sage.plot.plot3d.shapes import Sphere
        sage: Sphere(12).x3d_geometry()
        "<Sphere radius='12.0'/>"

    Python

        >>> from sage.all import *
        >>> from sage.plot.plot3d.shapes import Sphere
        >>> Sphere(Integer(12)).x3d_geometry()
        "<Sphere radius='12.0'/>"

class sage.plot.plot3d.shapes.Text(string, **kwds)

  Bases: `PrimitiveObject`

  A text label attached to a point in 3d space. It always starts at the origin, translate it to move it elsewhere.

  EXAMPLES:

  Sage

      sage: from sage.plot.plot3d.shapes import Text
      sage: Text("Just a lonely label.")
      Graphics3d Object

  Python

      >>> from sage.all import *
      >>> from sage.plot.plot3d.shapes import Text
      >>> Text("Just a lonely label.")
      Graphics3d Object

  Sage

      sage: pts = [(RealField(10)^3).random_element() for k in range(20)]
      sage: sum(Text(str(P)).translate(P) for P in pts)
      Graphics3d Object

  [Python]

      >>> from sage.all import *
      >>> pts = [(RealField(Integer(10))**Integer(3)).random_element() for k in range(Integer(20))]
      >>> sum(Text(str(P)).translate(P) for P in pts)
      Graphics3d Object

  bounding_box()

    Text labels have no extent:

    Sage

        sage: from sage.plot.plot3d.shapes import Text
        sage: Text("Hi").bounding_box()
        ((0, 0, 0), (0, 0, 0))

    Python

        >>> from sage.all import *
        >>> from sage.plot.plot3d.shapes import Text
        >>> Text("Hi").bounding_box()
        ((0, 0, 0), (0, 0, 0))

  jmol_repr(render_params)

    Labels in jmol must be attached to atoms.

    EXAMPLES:

    Sage

        sage: from sage.plot.plot3d.shapes import Text
        sage: T = Text("Hi")
        sage: T.jmol_repr(T.testing_render_params())
        ['select atomno = 1', 'color atom  [102,102,255]', 'label "Hi"']
        sage: T = Text("Hi").translate(-1, 0, 0) + Text("Bye").translate(1, 0, 0)
        sage: T.jmol_repr(T.testing_render_params())
        [[['select atomno = 1', 'color atom  [102,102,255]', 'label "Hi"']],
         [['select atomno = 2', 'color atom  [102,102,255]', 'label "Bye"']]]

    Python

        >>> from sage.all import *
        >>> from sage.plot.plot3d.shapes import Text
        >>> T = Text("Hi")
        >>> T.jmol_repr(T.testing_render_params())
        ['select atomno = 1', 'color atom  [102,102,255]', 'label "Hi"']
        >>> T = Text("Hi").translate(-Integer(1), Integer(0), Integer(0)) + Text("Bye").translate(Integer(1), Integer(0), Integer(0))
        >>> T.jmol_repr(T.testing_render_params())
        [[['select atomno = 1', 'color atom  [102,102,255]', 'label "Hi"']],
         [['select atomno = 2', 'color atom  [102,102,255]', 'label "Bye"']]]

  obj_repr(render_params)

    The obj file format does not support text strings:

    Sage

        sage: from sage.plot.plot3d.shapes import Text
        sage: Text("Hi").obj_repr(None)
        ''

    Python

        >>> from sage.all import *
        >>> from sage.plot.plot3d.shapes import Text
        >>> Text("Hi").obj_repr(None)
        ''

  tachyon_repr(render_params)

    Strings are not yet supported in Tachyon, so we ignore them for now:

    Sage

        sage: from sage.plot.plot3d.shapes import Text
        sage: Text("Hi").tachyon_repr(None)
        ''

    Python

        >>> from sage.all import *
        >>> from sage.plot.plot3d.shapes import Text
        >>> Text("Hi").tachyon_repr(None)
        ''

  threejs_repr(render_params)

    Return representation of the text suitable for plotting in three.js.

    EXAMPLES:

    Sage

        sage: T = text3d("Hi", (1, 2, 3), color='red', fontfamily='serif',
        ....:            fontweight='bold', fontstyle='italic', fontsize=20,
        ....:            opacity=0.5)
        sage: T.threejs_repr(T.default_render_params())
        [('text',
          {'color': '#ff0000',
           'fontFamily': ['serif'],
           'fontSize': 20.0,
           'fontStyle': 'italic',
           'fontWeight': 'bold',
           'opacity': 0.5,
           'text': 'Hi',
           'x': 1.0,
           'y': 2.0,
           'z': 3.0})]

    Python

        >>> from sage.all import *
        >>> T = text3d("Hi", (Integer(1), Integer(2), Integer(3)), color='red', fontfamily='serif',
        ...            fontweight='bold', fontstyle='italic', fontsize=Integer(20),
        ...            opacity=RealNumber('0.5'))
        >>> T.threejs_repr(T.default_render_params())
        [('text',
          {'color': '#ff0000',
           'fontFamily': ['serif'],
           'fontSize': 20.0,
           'fontStyle': 'italic',
           'fontWeight': 'bold',
           'opacity': 0.5,
           'text': 'Hi',
           'x': 1.0,
           'y': 2.0,
           'z': 3.0})]

  x3d_geometry()

    EXAMPLES:

    Sage

        sage: from sage.plot.plot3d.shapes import Text
        sage: Text("Hi").x3d_geometry()
        "<Text string='Hi' solid='true'/>"

    Python

        >>> from sage.all import *
        >>> from sage.plot.plot3d.shapes import Text
        >>> Text("Hi").x3d_geometry()
        "<Text string='Hi' solid='true'/>"

class sage.plot.plot3d.shapes.Torus

  Bases: `ParametricSurface`

  INPUT:

  - `R` – (default: `1`) outer radius

  - `r` – (default: `.3`) inner radius

  OUTPUT: a 3d torus

  EXAMPLES:

  Sage

      sage: from sage.plot.plot3d.shapes import Torus
      sage: Torus(1, .2).show(aspect_ratio=1)

  Python

      >>> from sage.all import *
      >>> from sage.plot.plot3d.shapes import Torus
      >>> Torus(Integer(1), RealNumber('.2')).show(aspect_ratio=Integer(1))

  Sage

      sage: Torus(1, .7, color='red').show(aspect_ratio=1)

  [Python]

      >>> from sage.all import *
      >>> Torus(Integer(1), RealNumber('.7'), color='red').show(aspect_ratio=Integer(1))

  A rubberband ball:

  Sage

      sage: show(sum(Torus(1, .03, color=(1, t/30.0, 0)).rotate((1,1,1), t)
      ....:          for t in range(30)))

  Python

      >>> from sage.all import *
      >>> show(sum(Torus(Integer(1), RealNumber('.03'), color=(Integer(1), t/RealNumber('30.0'), Integer(0))).rotate((Integer(1),Integer(1),Integer(1)), t)
      ...          for t in range(Integer(30))))

  Mmm… doughnuts:

  Sage

      sage: D = Torus(1, .4, color=(.5, .3, .2))
      sage: D += Torus(1, .3, color='yellow').translate(0, 0, .15)
      sage: G = sum(D.translate(RDF.random_element(-.2, .2),
      ....:                     RDF.random_element(-.2, .2),
      ....:                     .8*t)
      ....:         for t in range(10))
      sage: G.show(aspect_ratio=1, frame=False)

  [Python]

      >>> from sage.all import *
      >>> D = Torus(Integer(1), RealNumber('.4'), color=(RealNumber('.5'), RealNumber('.3'), RealNumber('.2')))
      >>> D += Torus(Integer(1), RealNumber('.3'), color='yellow').translate(Integer(0), Integer(0), RealNumber('.15'))
      >>> G = sum(D.translate(RDF.random_element(-RealNumber('.2'), RealNumber('.2')),
      ...                     RDF.random_element(-RealNumber('.2'), RealNumber('.2')),
      ...                     RealNumber('.8')*t)
      ...         for t in range(Integer(10)))
      >>> G.show(aspect_ratio=Integer(1), frame=False)

  get_grid(ds)

    Return the range of variables to be evaluated on to render as a parametric surface.

    EXAMPLES:

    Sage

        sage: from sage.plot.plot3d.shapes import Torus
        sage: Torus(2, 1).get_grid(100)
        ([0.0, -1.047..., -3.141592653589793, ..., 0.0],
         [0.0, 1.047..., 3.141592653589793, ..., 0.0])

    Python

        >>> from sage.all import *
        >>> from sage.plot.plot3d.shapes import Torus
        >>> Torus(Integer(2), Integer(1)).get_grid(Integer(100))
        ([0.0, -1.047..., -3.141592653589793, ..., 0.0],
         [0.0, 1.047..., 3.141592653589793, ..., 0.0])

sage.plot.plot3d.shapes.arrow3d(start, end, width=1, radius=None, head_radius=None, head_len=None, **kwds)

  Create a 3d arrow.

  INPUT:

  - `start` – (x,y,z) point; the starting point of the arrow

  - `end` – (x,y,z) point; the end point

  - `width` – (default: 1) how wide the arrow is

  - `radius` – (default: `width/50.0`) the radius of the arrow

  - `head_radius` – (default: `3*radius`) radius of arrow head

  - `head_len` – (default: `3*head_radius`) len of arrow head

  EXAMPLES:

  The default arrow:

  Sage

      sage: arrow3d((0,0,0), (1,1,1), 1)
      Graphics3d Object

  Python

      >>> from sage.all import *
      >>> arrow3d((Integer(0),Integer(0),Integer(0)), (Integer(1),Integer(1),Integer(1)), Integer(1))
      Graphics3d Object

  A fat arrow:

  Sage

      sage: arrow3d((0,0,0), (1,1,1), radius=0.1)
      Graphics3d Object

  [Python]

      >>> from sage.all import *
      >>> arrow3d((Integer(0),Integer(0),Integer(0)), (Integer(1),Integer(1),Integer(1)), radius=RealNumber('0.1'))
      Graphics3d Object

  A green arrow:

  Sage

      sage: arrow3d((0,0,0), (1,1,1), color='green')
      Graphics3d Object

  Python

      >>> from sage.all import *
      >>> arrow3d((Integer(0),Integer(0),Integer(0)), (Integer(1),Integer(1),Integer(1)), color='green')
      Graphics3d Object

  A fat arrow head:

  Sage

      sage: arrow3d((2,1,0), (1,1,1), color='green', head_radius=0.3,
      ....:         aspect_ratio=[1,1,1])
      Graphics3d Object

  [Python]

      >>> from sage.all import *
      >>> arrow3d((Integer(2),Integer(1),Integer(0)), (Integer(1),Integer(1),Integer(1)), color='green', head_radius=RealNumber('0.3'),
      ...         aspect_ratio=[Integer(1),Integer(1),Integer(1)])
      Graphics3d Object

  Many arrows arranged in a circle (flying spears?):

  Sage

      sage: sum(arrow3d((cos(t),sin(t),0), (cos(t),sin(t),1))                         # needs sage.symbolic
      ....:     for t in [0,0.3,..,2*pi])
      Graphics3d Object

  Python

      >>> from sage.all import *
      >>> sum(arrow3d((cos(t),sin(t),Integer(0)), (cos(t),sin(t),Integer(1)))                         # needs sage.symbolic
      ...     for t in (ellipsis_range(Integer(0),RealNumber('0.3'),Ellipsis,Integer(2)*pi)))
      Graphics3d Object

  Change the width of the arrow. (Note: for an arrow that scales with zoom, please consider the `line3d()` function with the option `arrow_head=True`):

  Sage

      sage: arrow3d((0,0,0), (1,1,1), width=1)
      Graphics3d Object

  [Python]

      >>> from sage.all import *
      >>> arrow3d((Integer(0),Integer(0),Integer(0)), (Integer(1),Integer(1),Integer(1)), width=Integer(1))
      Graphics3d Object

sage.plot.plot3d.shapes.validate_frame_size(size)

  Check that the input is an iterable of length 3 with all elements nonnegative and coercible to floats.

  EXAMPLES:

  Sage

      sage: from sage.plot.plot3d.shapes import validate_frame_size
      sage: validate_frame_size([3,2,1])
      [3.0, 2.0, 1.0]

  Python

      >>> from sage.all import *
      >>> from sage.plot.plot3d.shapes import validate_frame_size
      >>> validate_frame_size([Integer(3),Integer(2),Integer(1)])
      [3.0, 2.0, 1.0]