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
""" Basic objects such as Sphere, Box, Cone, etc.
AUTHORS:
- Robert Bradshaw 2007-02: initial version - Robert Bradshaw 2007-08: obj/tachon rendering, much updating - Robert Bradshaw 2007-08: cythonization
EXAMPLES::
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) + Sphere(.05, color='black').translate(.51,-.1,.17) sage: S += Sphere(.1, color='white').translate(.45, .1,.15) + 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()
.. PLOT::
from sage.plot.plot3d.shapes import * S = Sphere(.5, color='yellow') S += Cone(.5, .5, color='red').translate(0,0,.3) S += Sphere(.1, color='white').translate(.45,-.1,.15) + Sphere(.05, color='black').translate(.51,-.1,.17) S += Sphere(.1, color='white').translate(.45, .1,.15) + Sphere(.05, color='black').translate(.51, .1,.17) S += Sphere(.1, color='yellow').translate(.5, 0, -.2) sphinx_plot(S)
::
sage: from sage.plot.plot3d.shapes import * sage: Torus(.7, .2, color=(0,.3,0)).show()
.. PLOT::
from sage.plot.plot3d.shapes import * sphinx_plot(Torus(.7, .2, color=(0,.3,0)))
"""
#***************************************************************************** # Copyright (C) 2007 Robert Bradshaw <robertwb@math.washington.edu> # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # http://www.gnu.org/licenses/ #***************************************************************************** from __future__ import absolute_import
from libc.math cimport sqrt, sin, cos, tan, asin, acos, atan, M_PI from sage.rings.real_double import RDF from sage.modules.free_module_element import vector from sage.plot.misc import rename_keyword from .base import Graphics3dGroup, Graphics3d from .index_face_set cimport IndexFaceSet, PrimitiveObject from .transform cimport point_c
# Helper function to check that Box input is right def validate_frame_size(size): """ Check that the input is an iterable of length 3 with all elements nonnegative and coercible to floats.
EXAMPLES::
sage: from sage.plot.plot3d.shapes import validate_frame_size sage: validate_frame_size([3,2,1]) [3.0, 2.0, 1.0]
TESTS::
sage: from sage.plot.plot3d.shapes import validate_frame_size sage: validate_frame_size([3,2,-1]) Traceback (most recent call last): ... ValueError: each box dimension must be nonnegative sage: validate_frame_size([sqrt(-1),3,2]) Traceback (most recent call last): ... TypeError: each box dimension must coerce to a float """ raise TypeError("size must be a list or tuple") raise TypeError("size must be of length 3")
class Box(IndexFaceSet): """ Return a box.
EXAMPLES::
sage: from sage.plot.plot3d.shapes import Box
A square black box::
sage: show(Box([1,1,1]), color='black')
.. PLOT::
from sage.plot.plot3d.shapes import Box sphinx_plot(Box([1,1,1], color='black'))
A red rectangular box::
sage: show(Box([2,3,4], color="red"))
.. PLOT::
from sage.plot.plot3d.shapes import Box sphinx_plot(Box([2,3,4], color="red"))
A stack of boxes::
sage: show(sum([Box([2,3,1], color="red").translate((0,0,6*i)) for i in [0..3]]))
.. PLOT::
from sage.plot.plot3d.shapes import Box P = sum([Box([2,3,1], color="red").translate((0,0,6*i)) for i in range(0,4)]) sphinx_plot(P)
A sinusoidal stack of multicolored boxes::
sage: B = sum([Box([2,4,1/4], color=(i/4,i/5,1)).translate((sin(i),0,5-i)) for i in [0..20]]) sage: show(B, figsize=6)
.. PLOT::
from sage.plot.plot3d.shapes import Box B = sum([Box([2,4,1/4], color=(i/4.0,i/5.0,1)).translate((sin(i),0,5-i)) for i in range(0,21)]) sphinx_plot(B)
""" def __init__(self, *size, **kwds): """ EXAMPLES::
sage: from sage.plot.plot3d.shapes import Box sage: Box(10, 1, 1) + Box(1, 10, 1) + Box(1, 1, 10) Graphics3d Object """
def bounding_box(self): """ EXAMPLES::
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)) """
def x3d_geometry(self): """ EXAMPLES::
sage: from sage.plot.plot3d.shapes import Box sage: Box([1,2,1/4]).x3d_geometry() "<Box size='1.0 2.0 0.25'/>" """
def 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`` -- a 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: 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()
.. PLOT::
from sage.plot.plot3d.shapes import ColorCube c = ColorCube([1,2,3], ['red', 'blue', 'green', 'black', 'white', 'orange'], opacity=0.5) sphinx_plot(c)
::
sage: list(c.texture_set())[0].opacity 0.5
If you omit the last 3 colors then the first three are repeated (with repeated colors on opposing faces)::
sage: c = ColorCube([0.5,0.5,0.5], ['red', 'blue', 'green'])
.. PLOT::
from sage.plot.plot3d.shapes import ColorCube c = ColorCube([0.5,0.5,0.5], ['red', 'blue', 'green']) sphinx_plot(c)
"""
cdef class Cone(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: from sage.plot.plot3d.shapes import Cone sage: c = Cone(3/2, 1, color='red') + Cone(1, 2, color='yellow').translate(3, 0, 0) sage: c.show(aspect_ratio=1)
.. PLOT::
from sage.plot.plot3d.shapes import Cone c = Cone(3/2, 1, color='red') + Cone(1, 2, color='yellow').translate(3, 0, 0) sphinx_plot(c)
We may omit the base::
sage: Cone(1, 1, closed=False) Graphics3d Object
.. PLOT::
from sage.plot.plot3d.shapes import Cone sphinx_plot(Cone(1, 1, closed=False))
A spiky plot of the sine function::
sage: sum(Cone(.1, sin(n), color='yellow').translate(n, sin(n), 0) for n in [0..10, step=.1]) Graphics3d Object
.. PLOT::
from sage.plot.plot3d.shapes import Cone sphinx_plot(sum(Cone(.1, sin(n/10.0), color='yellow').translate(n/10.0, sin(n/10.0), 0) for n in range(0,100)))
A Christmas tree::
sage: T = sum(Cone(exp(-n/5), 4/3*exp(-n/5), 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) sage: T.show(aspect_ratio=1, frame=False)
.. PLOT::
from sage.plot.plot3d.shapes import Cone T = sum(Cone(exp(-n/5.0), 4/3*exp(-n/5.0), color=(0, .5, 0)).translate(0, 0, -3*exp(-n/5.0)) for n in range(8)) T += Cone(1/8, 1, color='brown').translate(0, 0, -3) sphinx_plot(T)
""" def __init__(self, radius, height, closed=True, **kwds): """ TESTS::
sage: from sage.plot.plot3d.shapes import Cone sage: c = Cone(1/2, 1, opacity=.5) """
def x3d_geometry(self): """ EXAMPLES::
sage: from sage.plot.plot3d.shapes import Cone sage: Cone(1, 3).x3d_geometry() "<Cone bottomRadius='1.0' height='3.0'/>" """
def get_grid(self, ds): """ Return the grid on which to evaluate this parametric surface.
EXAMPLES::
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 """ else:
cdef int eval_c(self, point_c *res, double u, double v) except -1: else: # u == 1:
cdef class Cylinder(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: from sage.plot.plot3d.shapes import Cylinder sage: c = Cylinder(3/2, 1, color='red') + Cylinder(1, 2, color='yellow').translate(3, 0, 0) sage: c.show(aspect_ratio=1)
.. PLOT::
from sage.plot.plot3d.shapes import Cylinder c = Cylinder(3/2, 1, color='red') + Cylinder(1, 2, color='yellow').translate(3, 0, 0) sphinx_plot(c)
We may omit the base::
sage: Cylinder(1, 1, closed=False) Graphics3d Object
.. PLOT::
from sage.plot.plot3d.shapes import Cylinder sphinx_plot(Cylinder(1, 1, closed=False))
Some gears::
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)
.. PLOT::
from sage.plot.plot3d.shapes import Cylinder G = Cylinder(1, .5) + Cylinder(.25, 3).translate(0, 0, -3) G += sum(Cylinder(.2, 1).translate(cos(2*pi*n/9.0), sin(2*pi*n/9.0), 0) for n in range(10)) G += G.translate(2.3, 0, -.5) G += G.translate(3.5, 2, -1) sphinx_plot(G)
""" def __init__(self, radius, height, closed=True, **kwds): """ TESTS::
sage: from sage.plot.plot3d.shapes import Cylinder sage: Cylinder(1, 1, color='red') Graphics3d Object """
def bounding_box(self): """ EXAMPLES::
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)) """
def x3d_geometry(self): """ EXAMPLES::
sage: from sage.plot.plot3d.shapes import Cylinder sage: Cylinder(1, 2).x3d_geometry() "<Cylinder radius='1.0' height='2.0'/>" """
def tachyon_repr(self, render_params): r""" EXAMPLES::
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...'] """ # Tachyon can't do squashed
cyl = """FCylinder Base %s %s %s Apex %s %s %s Rad %s base_cap = """Ring Center %s %s %s Normal %s %s %s Inner 0 Outer %s %s""" \ top_cap = """Ring Center %s %s %s Normal %s %s %s Inner 0 Outer %s %s""" \ else:
def jmol_repr(self, render_params): r""" EXAMPLES::
sage: from sage.plot.plot3d.shapes import Cylinder
For thin cylinders, lines are used::
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']
For anything larger, we use a pmesh::
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]'] """
# Jmol can't do squashed
draw %s width %s {%s %s %s} {%s %s %s}\n%s rad,
def get_endpoints(self, transform=None): """ EXAMPLES::
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)) """ else:
def get_radius(self, transform=None): """ EXAMPLES::
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 """
def get_grid(self, ds): """ Return the grid on which to evaluate this parametric surface.
EXAMPLES::
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 """ else:
cdef int eval_c(self, point_c *res, double u, double v) except -1: else: # u == 2:
def 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: 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()
.. PLOT::
from sage.plot.plot3d.shapes import LineSegment, Sphere P = (0,0,0.1) Q = (0.5,0.6,0.7) S = Sphere(.2, color='red').translate(P) S += Sphere(.2, color='blue').translate(Q) S += LineSegment(P, Q, .05, color='black') sphinx_plot(S)
::
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()
.. PLOT::
from sage.plot.plot3d.shapes import LineSegment, Sphere P = (0,0,0.1) Q = (0.5,0.6,0.7) S = Sphere(.1, color='red').translate(P) S += Sphere(.1, color='blue').translate(Q) S += LineSegment(P, Q, .15, color='black') sphinx_plot(S)
AUTHOR:
- Robert Bradshaw """ return cyl.translate(end) else: else:
@rename_keyword(deprecation=7154, deprecated_option='thickness', thickness='width') def 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: arrow3d((0,0,0), (1,1,1), 1) Graphics3d Object
.. PLOT::
sphinx_plot(arrow3d((0,0,0), (1,1,1), 1))
A fat arrow::
sage: arrow3d((0,0,0), (1,1,1), radius=0.1) Graphics3d Object
.. PLOT::
sphinx_plot(arrow3d((0,0,0), (1,1,1), radius=0.1))
A green arrow::
sage: arrow3d((0,0,0), (1,1,1), color='green') Graphics3d Object
.. PLOT::
sphinx_plot(arrow3d((0,0,0), (1,1,1), color='green'))
A fat arrow head::
sage: arrow3d((2,1,0), (1,1,1), color='green', head_radius=0.3, aspect_ratio=[1,1,1]) Graphics3d Object
.. PLOT::
sphinx_plot(arrow3d((2,1,0), (1,1,1), color='green', head_radius=0.3, aspect_ratio=[1,1,1]))
Many arrows arranged in a circle (flying spears?)::
sage: sum([arrow3d((cos(t),sin(t),0),(cos(t),sin(t),1)) for t in [0,0.3,..,2*pi]]) Graphics3d Object
.. PLOT::
t=0 G=Graphics() while (t<=2*pi): G += arrow3d((cos(t),sin(t),0),(cos(t),sin(t),1)) t +=0.3 sphinx_plot(G)
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: arrow3d((0,0,0), (1,1,1), width=1) Graphics3d Object
.. PLOT::
sphinx_plot(arrow3d((0,0,0), (1,1,1), width=1))
TESTS:
If the arrow is too long, the shaft and part of the head is cut off. ::
sage: a = arrow3d((0,0,0), (0,0,0.5), head_len=1) sage: len(a.all) 1 sage: type(a.all[0]) <... 'sage.plot.plot3d.shapes.Cone'>
Arrows are always constructed pointing up in the z direction from the origin, and then rotated/translated into place. This works for every arrow direction except the -z direction. We take care of the anomaly by testing to see if the arrow should point in the -z direction, and if it should, just scaling the constructed arrow by -1 (i.e., every point is sent to its negative). The scaled arrow then points downwards. The doctest just tests that the scale of -1 is applied to the arrow. ::
sage: a = arrow3d((0,0,0), (0,0,-1)) sage: a.all[0].get_transformation().transform_point((0,0,1)) (0.0, 0.0, -1.0) """ else: else: else:
cdef class Sphere(ParametricSurface): """ This class represents a sphere centered at the origin.
EXAMPLES::
sage: from sage.plot.plot3d.shapes import Sphere sage: Sphere(3) Graphics3d Object
.. PLOT::
from sage.plot.plot3d.shapes import Sphere sphinx_plot(Sphere(3))
Plot with aspect_ratio=1 to see it unsquashed::
sage: S = Sphere(3, color='blue') + Sphere(2, color='red').translate(0,3,0) sage: S.show(aspect_ratio=1)
.. PLOT::
from sage.plot.plot3d.shapes import Sphere S = Sphere(3, color='blue') + Sphere(2, color='red').translate(0,3,0) sphinx_plot(S)
Scale to get an ellipsoid::
sage: S = Sphere(1).scale(1,2,1/2) sage: S.show(aspect_ratio=1)
.. PLOT::
from sage.plot.plot3d.shapes import Sphere S = Sphere(1).scale(1,2,1/2) sphinx_plot(S)
""" def __init__(self, radius, **kwds): """ TESTS::
sage: from sage.plot.plot3d.shapes import Sphere sage: Sphere(3) Graphics3d Object """
def bounding_box(self): """ Return the bounding box that contains this sphere.
EXAMPLES::
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)) """
def x3d_geometry(self): """ EXAMPLES::
sage: from sage.plot.plot3d.shapes import Sphere sage: Sphere(12).x3d_geometry() "<Sphere radius='12.0'/>" """
def tachyon_repr(self, render_params): r""" Tachyon can natively handle spheres. Ellipsoids rendering is done as a parametric surface.
EXAMPLES::
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...']] """
else:
def jmol_repr(self, render_params): r""" EXAMPLES::
sage: from sage.plot.plot3d.shapes import Sphere
Jmol has native code for handling spheres::
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]']]
It cannot natively handle ellipsoids::
sage: Sphere(1).scale(2, 3, 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: 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]'] """
else: else:
def get_grid(self, double ds): """ Return the range of variables to be evaluated on to render as a parametric surface.
EXAMPLES::
sage: from sage.plot.plot3d.shapes import Sphere sage: Sphere(1).get_grid(100) ([-10.0, ..., 0.0, ..., 10.0], [0.0, ..., 3.141592653589793, ..., 0.0]) """ cdef int K, u_res, v_res
cdef int eval_c(self, point_c *res, double u, double v) except -1: else:
cdef class Torus(ParametricSurface): """ INPUT:
- R -- (default: 1) outer radius - r -- (default: .3) inner radius
OUTPUT:
a 3d torus
EXAMPLES::
sage: from sage.plot.plot3d.shapes import Torus sage: Torus(1, .2).show(aspect_ratio=1)
.. PLOT::
from sage.plot.plot3d.shapes import Torus sphinx_plot(Torus(1, .2))
::
sage: Torus(1, .7, color='red').show(aspect_ratio=1)
.. PLOT::
from sage.plot.plot3d.shapes import Torus sphinx_plot(Torus(1, .7, color='red'))
A rubberband ball::
sage: show(sum([Torus(1, .03, color=(1, t/30.0, 0)).rotate((1,1,1),t) for t in range(30)]))
.. PLOT::
from sage.plot.plot3d.shapes import Torus sphinx_plot(sum([Torus(1, .03, color=(1, t/30.0, 0)).rotate((1,1,1),t) for t in range(30)]))
Mmm... doughnuts::
sage: D = Torus(1, .4, color=(.5, .3, .2)) + 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)
.. PLOT::
from sage.plot.plot3d.shapes import Torus D = Torus(1, .4, color=(.5, .3, .2)) + Torus(1, .3, color='yellow').translate(0, 0, .15) G = sum(D.translate(RDF.random_element(-.2, .2), RDF.random_element(-.2, .2), .8*t) for t in range(10)) sphinx_plot(G)
""" def __init__(self, R=1, r=.3, **kwds): """ TESTS::
sage: from sage.plot.plot3d.shapes import Torus sage: T = Torus(1, .5) """
def get_grid(self, ds): """ Return the range of variables to be evaluated on to render as a parametric surface.
EXAMPLES::
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]) """ cdef int k, u_divs, v_divs
cdef int eval_c(self, point_c *res, double u, double v) except -1:
class Text(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: from sage.plot.plot3d.shapes import Text sage: Text("Just a lonely label.") Graphics3d Object
.. PLOT::
from sage.plot.plot3d.shapes import Text sphinx_plot(Text("Just a lonely label. "))
::
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
.. PLOT::
from sage.plot.plot3d.shapes import Text pts = [(RealField(10)**3).random_element() for k in range(20)] sphinx_plot(sum(Text(str(P)).translate(P) for P in pts))
""" def __init__(self, string, **kwds): """ TESTS::
sage: from sage.plot.plot3d.shapes import Text sage: T = Text("Hi") """
def x3d_geometry(self): """ EXAMPLES::
sage: from sage.plot.plot3d.shapes import Text sage: Text("Hi").x3d_geometry() "<Text string='Hi' solid='true'/>" """
def obj_repr(self, render_params): """ The obj file format does not support text strings::
sage: from sage.plot.plot3d.shapes import Text sage: Text("Hi").obj_repr(None) '' """
def tachyon_repr(self, render_params): """ Strings are not yet supported in Tachyon, so we ignore them for now::
sage: from sage.plot.plot3d.shapes import Text sage: Text("Hi").tachyon_repr(None) '' """ # Text in Tachyon not implemented yet. # I have no idea what the code below is supposed to do. ## transform = render_params.transform ## if not (transform is None or transform.is_uniform()): ## return ParametricSurface.tachyon_repr(self, render_params) ## ## if transform is None: ## cen = (0,0,0) ## rad = self.radius ## else: ## cen = transform.transform_point((0,0,0)) ## radv = transform.transform_vector((self.radius,0,0)) ## rad = sqrt(sum([x*x for x in radv])) ## return "Sphere center %s %s %s Rad %s %s" % (cen[0], cen[1], cen[2], rad, self.texture.id)
def jmol_repr(self, render_params): """ Labels in jmol must be attached to atoms.
EXAMPLES::
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"']]] """
def bounding_box(self): """ Text labels have no extent::
sage: from sage.plot.plot3d.shapes import Text sage: Text("Hi").bounding_box() ((0, 0, 0), (0, 0, 0)) """ |