Scripts: ylm.py

File ylm.py, 2.3 KB (added by goddard, 6 years ago)
Line 
1# Make a spherical harmonic surface.
2
3from math import sin, cos, pi, sqrt
4
5def spherical_surface(session,
6 radius_function,
7 theta_steps = 100,
8 phi_steps = 50,
9 positive_color = (255,100,100,255), # red, green, blue, alpha, 0-255
10 negative_color = (100,100,255,255)):
11
12 # Compute vertices and vertex colors
13 vertices = []
14 colors = []
15 for t in range(theta_steps):
16 theta = (t/theta_steps) * 2*pi
17 ct, st = cos(theta), sin(theta)
18 for p in range(phi_steps):
19 phi = (p/(phi_steps-1)) * pi
20 cp, sp = cos(phi), sin(phi)
21 r = radius_function(theta, phi)
22 xyz = (r*sp*ct, r*sp*st, r*cp)
23 vertices.append(xyz)
24 color = positive_color if r >= 0 else negative_color
25 colors.append(color)
26
27 # Compute triangles, triples of vertex indices
28 triangles = []
29 for t in range(theta_steps):
30 for p in range(phi_steps-1):
31 i = t*phi_steps + p
32 t1 = (t+1)%theta_steps
33 i1 = t1*phi_steps + p
34 triangles.append((i,i+1,i1+1))
35 triangles.append((i,i1+1,i1))
36
37 # Create numpy arrays
38 from numpy import array, float32, uint8, int32
39 va = array(vertices, float32)
40 ca = array(colors, uint8)
41 ta = array(triangles, int32)
42
43 # Compute average vertex normal vectors
44 from chimerax.surface import calculate_vertex_normals
45 na = calculate_vertex_normals(va, ta)
46
47 # Create ChimeraX surface model
48 from chimerax.core.models import Surface
49 s = Surface('surface', session)
50 s.set_geometry(va, na, ta)
51 s.vertex_colors = ca
52 session.models.add([s])
53
54 return s
55
56# Example spherical harmonic function Y(l=2,m=0) real part.
57def y20_re(theta, phi):
58 return 0.25*sqrt(5/pi) * (3*cos(phi)**2 - 1)
59def y21_re(theta, phi):
60 return -0.5*sqrt(15/(2*pi)) * sin(phi)*cos(phi) * cos(theta)
61def y22_re(theta, phi):
62 return 0.25*sqrt(15/(2*pi)) * sin(phi)**2 * cos(2*theta)
63
64# Create 3 surfaces
65spherical_surface(session, y20_re)
66
67s1 = spherical_surface(session, y21_re)
68from chimerax.geometry import translation
69s1.position = translation((1,0,0))
70
71s2 = spherical_surface(session, y22_re)
72s2.position = translation((2,0,0))