This example is taken from pythreejs GitHub page
pythreejs has been installed by
sage -pip install pythreejs
sage -sh jupyter nbextension enable --py --sys-prefix pythreejs
sage -pip install scikit-image
The version of SageMath:
version()
'SageMath version 7.5.beta4, Release Date: 2016-11-24'
from pythreejs import *
import numpy as np
from IPython.display import display
from ipywidgets import HTML, Text
from traitlets import link, dlink
/home/eric/sage/7.5.beta4/local/lib/python2.7/site-packages/pythreejs/pythreejs.py:58: DeprecationWarning: Traits should be given as instances, not types (for example, `Int()`, not `Int`) data = List(CInt).tag(sync=True) /home/eric/sage/7.5.beta4/local/lib/python2.7/site-packages/pythreejs/pythreejs.py:88: DeprecationWarning: metadata {'sync': True} was set from the constructor. Metadata should be set using the .tag() method, e.g., Int().tag(key1='value1', key2='value2') string = Unicode(sync=True) /home/eric/sage/7.5.beta4/local/lib/python2.7/site-packages/pythreejs/pythreejs.py:24: DeprecationWarning: Traits should be given as instances, not types (for example, `Int()`, not `Int`) return List(trait_type, default_value=default, minlen=3, maxlen=3, **kwargs) /home/eric/sage/7.5.beta4/local/lib/python2.7/site-packages/pythreejs/pythreejs.py:102: DeprecationWarning: Traits should be given as instances, not types (for example, `Int()`, not `Int`) quaternion = List(CFloat).tag(sync=True) # [x,y,z,w] /home/eric/sage/7.5.beta4/local/lib/python2.7/site-packages/pythreejs/pythreejs.py:249: DeprecationWarning: Traits should be given as instances, not types (for example, `Int()`, not `Int`) picked = List(Dict).tag(sync=True) /home/eric/sage/7.5.beta4/local/lib/python2.7/site-packages/pythreejs/pythreejs.py:272: DeprecationWarning: Traits should be given as instances, not types (for example, `Int()`, not `Int`) colors = List(Color).tag(sync=True) /home/eric/sage/7.5.beta4/local/lib/python2.7/site-packages/pythreejs/pythreejs.py:273: DeprecationWarning: Traits should be given as instances, not types (for example, `Int()`, not `Int`) faces = List(List(CFloat)).tag(sync=True) /home/eric/sage/7.5.beta4/local/lib/python2.7/site-packages/pythreejs/pythreejs.py:403: DeprecationWarning: Traits should be given as instances, not types (for example, `Int()`, not `Int`) vertices = List(List(CFloat)).tag(sync=True) /home/eric/sage/7.5.beta4/local/lib/python2.7/site-packages/pythreejs/pythreejs.py:404: DeprecationWarning: Traits should be given as instances, not types (for example, `Int()`, not `Int`) faces = List(List(CInt)).tag(sync=True) /home/eric/sage/7.5.beta4/local/lib/python2.7/site-packages/pythreejs/pythreejs.py:426: DeprecationWarning: Traits should be given as instances, not types (for example, `Int()`, not `Int`) z = List(CFloat, [0] * 100).tag(sync=True) /home/eric/sage/7.5.beta4/local/lib/python2.7/site-packages/pythreejs/pythreejs.py:440: DeprecationWarning: Traits should be given as instances, not types (for example, `Int()`, not `Int`) vertices = List(CFloat).tag(sync=True) # [x0, y0, z0, x1, y1, z1, x2, y2, z2, ...] /home/eric/sage/7.5.beta4/local/lib/python2.7/site-packages/pythreejs/pythreejs.py:441: DeprecationWarning: Traits should be given as instances, not types (for example, `Int()`, not `Int`) face3 = List(CInt).tag(sync=True) # [v0,v1,v2, v0,v1,v2, v0,v1,v2, ...] /home/eric/sage/7.5.beta4/local/lib/python2.7/site-packages/pythreejs/pythreejs.py:442: DeprecationWarning: Traits should be given as instances, not types (for example, `Int()`, not `Int`) face4 = List(CInt).tag(sync=True) # [v0,v1,v2,v3, v0,v1,v2,v3, v0,v1,v2,v3, ...] /home/eric/sage/7.5.beta4/local/lib/python2.7/site-packages/pythreejs/pythreejs.py:443: DeprecationWarning: Traits should be given as instances, not types (for example, `Int()`, not `Int`) facen = List(List(CInt)).tag(sync=True) # [[v0,v1,v2,...,vn], [v0,v1,v2,...,vn], [v0,v1,v2,...,vn], ...] /home/eric/sage/7.5.beta4/local/lib/python2.7/site-packages/pythreejs/pythreejs.py:450: DeprecationWarning: metadata {'sync': True} was set from the constructor. Metadata should be set using the .tag() method, e.g., Int().tag(key1='value1', key2='value2') func = Unicode(sync=True) /home/eric/sage/7.5.beta4/local/lib/python2.7/site-packages/pythreejs/pythreejs.py:462: DeprecationWarning: metadata {'sync': True} was set from the constructor. Metadata should be set using the .tag() method, e.g., Int().tag(key1='value1', key2='value2') name = Unicode(sync=True) /home/eric/sage/7.5.beta4/local/lib/python2.7/site-packages/pythreejs/pythreejs.py:615: DeprecationWarning: Traits should be given as instances, not types (for example, `Int()`, not `Int`) uvScale = List(CFloat).tag(sync=True) /home/eric/sage/7.5.beta4/local/lib/python2.7/site-packages/pythreejs/pythreejs.py:618: DeprecationWarning: Traits should be given as instances, not types (for example, `Int()`, not `Int`) uvOffset = List(CFloat).tag(sync=True) /home/eric/sage/7.5.beta4/local/lib/python2.7/site-packages/pythreejs/pythreejs.py:622: DeprecationWarning: Traits should be given as instances, not types (for example, `Int()`, not `Int`) alignment = List(CFloat).tag(sync=True)
ball = Mesh(geometry=SphereGeometry(radius=1),
material=LambertMaterial(color='red'),
position=[2, 1, 0])
scene = Scene(children=[ball, AmbientLight(color='#777777')])
c = PerspectiveCamera(position=[0, 5, 5], up=[0, 0, 1],
children=[DirectionalLight(color='white',
position=[3, 5, 1],
intensity=0.5)])
renderer = Renderer(camera=c,
scene=scene,
controls=[OrbitControls(controlling=c)])
display(renderer)
ball.geometry.radius = 0.5
import time, math
ball.material.color = '#4400dd'
for i in range(1, 150, 2):
ball.geometry.radius = i / 100.
ball.position = [math.cos(i / 10.), math.sin(i / 50.), i / 100.]
time.sleep(.05)
nx, ny = (20, 20)
xmax=1
x = np.linspace(-xmax, xmax, nx)
y = np.linspace(-xmax, xmax, ny)
xx, yy = np.meshgrid(x, y)
z = xx ** 2 - yy ** 2
#z[6,1] = float('nan')
surf_g = SurfaceGeometry(z=list(z[::-1].flat),
width=2 * xmax,
height=2 * xmax,
width_segments=nx - 1,
height_segments=ny - 1)
surf = Mesh(geometry=surf_g, material=LambertMaterial(map=height_texture(z[::-1], 'YlGnBu_r')))
surfgrid = SurfaceGrid(geometry=surf_g, material=LineBasicMaterial(color='black'))
hover_point = Mesh(geometry=SphereGeometry(radius=0.05), material=LambertMaterial(color='hotpink'))
scene = Scene(children=[surf, surfgrid, hover_point, AmbientLight(color='#777777')])
c = PerspectiveCamera(position=[0, 3, 3], up=[0, 0, 1],
children=[DirectionalLight(color='white', position=[3, 5, 1], intensity=0.6)])
click_picker = Picker(root=surf, event='dblclick')
hover_picker = Picker(root=surf, event='mousemove')
renderer = Renderer(camera=c, scene = scene, controls=[OrbitControls(controlling=c), click_picker, hover_picker])
def f(change):
value = change['new']
print('Clicked on %s' % value)
point = Mesh(geometry=SphereGeometry(radius=0.05),
material=LambertMaterial(color='red'),
position=value)
scene.children = list(scene.children) + [point]
click_picker.observe(f, names=['point'])
link((hover_point, 'position'), (hover_picker, 'point'))
h = HTML()
def g(change):
h.value = 'Green point at (%.3f, %.3f, %.3f)' % tuple(change['new'])
g({'new': hover_point.position})
hover_picker.observe(g, names=['point'])
display(h)
display(renderer)
# when we change the z values of the geometry, we need to also change the height map
surf_g.z = list((-z[::-1]).flat)
surf.material.map = height_texture(-z[::-1])
import numpy as np
from scipy import ndimage
import matplotlib
import matplotlib.pyplot as plt
from skimage import img_as_ubyte
jet = matplotlib.cm.get_cmap('jet')
np.random.seed(int(1)) # start random number generator
n = int(5) # starting points
size = int(32) # size of image
im = np.zeros((size,size)) # create zero image
points = size*np.random.random((2, n**2)) # locations of seed values
im[(points[0]).astype(np.int), (points[1]).astype(np.int)] = size # seed high values
im = ndimage.gaussian_filter(im, sigma=size/(float(4)*n)) # smooth high values into surrounding areas
im *= 1/np.max(im)# rescale to be in the range [0,1]
rgba_im = img_as_ubyte(jet(im)) # convert the values to rgba image using the jet colormap
rgba_list = list(rgba_im.flat) # make a flat list
t = DataTexture(data=rgba_list, format='RGBAFormat', width=size, height=size)
geometry = SphereGeometry()#TorusKnotGeometry(radius=2, radialSegments=200)
material = LambertMaterial(map=t)
myobject = Mesh(geometry=geometry, material=material)
c = PerspectiveCamera(position=[0, 3, 3], fov=40,
children=[DirectionalLight(color='#ffffff', position=[3, 5, 1], intensity=0.5)])
scene = Scene(children=[myobject, AmbientLight(color='#777777')])
renderer = Renderer(camera=c, scene = scene, controls=[OrbitControls(controlling=c)])
display(renderer)
# On windows, linewidth of the material has no effect
size = 4
linesgeom = PlainGeometry(vertices=[[0, 0, 0],
[size, 0, 0],
[0, 0, 0],
[0, size, 0],
[0, 0, 0],
[0, 0, size]],
colors = ['red', 'red', 'green', 'green', 'white', 'orange'])
lines = Line(geometry=linesgeom,
material=LineBasicMaterial(linewidth=5, vertexColors='VertexColors'),
type='LinePieces')
scene = Scene(children=[lines, DirectionalLight(color='#ccaabb', position=[0,10,0]),AmbientLight(color='#cccccc')])
c = PerspectiveCamera(position=[0, 10, 10])
renderer = Renderer(camera=c, scene = scene, controls=[OrbitControls(controlling=c)])
display(renderer)
To use the ParametricGeometry class, you need to specify a javascript function as a string. The function should take two parameters that vary between 0 and 1, and return a new THREE.Vector3(x,y,z)
.
If you want to build the surface in Python, you'll need to explicitly construct the vertices and faces and build a basic geometry from the vertices and faces.
f = """
function f(origu,origv) {
// scale u and v to the ranges I want: [0, 2*pi]
var u = 2*Math.PI*origu;
var v = 2*Math.PI*origv;
var x = Math.sin(u);
var y = Math.cos(v);
var z = Math.cos(u+v);
return new THREE.Vector3(x,y,z)
}
"""
surf_g = ParametricGeometry(func=f);
surf = Mesh(geometry=surf_g, material=LambertMaterial(color='green', side='FrontSide'))
surf2 = Mesh(geometry=surf_g, material=LambertMaterial(color='yellow', side='BackSide'))
scene = Scene(children=[surf, surf2, AmbientLight(color='#777777')])
c = PerspectiveCamera(position=[5, 5, 3], up=[0, 0, 1],
children=[DirectionalLight(color='white',
position=[3, 5, 1],
intensity=0.6)])
renderer = Renderer(camera=c, scene=scene, controls=[OrbitControls(controlling=c)])
display(renderer)