# Ellipsoid

The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

This script provides methods that create cgos as triangles. It uses code that is ported from this c++ code and seems to be correct!

Here is the script. The last four lines show this in use, by making an ellipse and a toroid and loading them into pymol. This is done most easily by something like "cmd.load_cgo(makeEllipsoid(1, 1, 1, 2, 3, 4), 'ellipsoid')" which makes an ellipsoid at x, y, z = 1, 1, 1 and dimensions 2, 3, 4 and called 'ellipsoid'.

from pymol.cgo import BEGIN, COLOR, TRIANGLES, VERTEX, NORMAL, END
from pymol import cmd

def signOfFloat(f):
if f < 0: return -1
if f > 0: return 1
return 0

def sqC(v, n):
return signOfFloat(math.cos(v)) *  math.pow(math.fabs(math.cos(v)), n)

def sqCT(v, n, alpha):
return alpha + sqC(v, n)

def sqS(v, n):
return signOfFloat(math.sin(v)) * math.pow(math.fabs(math.sin(v)), n)

def sqEllipsoid(x, y, z, a1, a2, a3, u, v, n, e):
x = a1 * sqC(u, n) * sqC(v, e) + x
y = a2 * sqC(u, n) * sqS(v, e) + y
z = a3 * sqS(u, n) + z
nx = sqC(u, 2 - n) * sqC(v, 2 - e) / a1
ny = sqC(u, 2 - n) * sqS(v, 2 - e) / a2
nz = sqS(u, 2 - n) / a3
return x, y, z, nx, ny, nz

def sqToroid(x, y, z, a1, a2, a3, u, v, n, e, alpha):
a1prime = 1.0 / (a1 + alpha)
a2prime = 1.0 / (a2 + alpha)
a3prime = 1.0 / (a3 + alpha)
x = a1prime * sqCT(u, e, alpha) * sqC(v, n)
y = a2prime * sqCT(u, e, alpha) * sqS(v, n)
z = a3prime * sqS(u, e)
nx = sqC(u, 2 - e) * sqC(v, 2 - n) / a1prime
ny = sqC(u, 2 - e) * sqS(v, 2 - n) / a2prime
nz = sqS(u, 2 - e) / a3prime
return x, y, z, nx, ny, nz

def makeSuperQuadricEllipsoid(x, y, z, a1, a2, a3, n, e, u1, u2, v1, v2, u_segs, v_segs, color=[0.5, 0.5, 0.5]):

r, g, b = color

# Calculate delta variables */
dU = (u2 - u1) / u_segs
dV = (v2 - v1) / v_segs

o = [ BEGIN, TRIANGLES ]

U = u1
for Y in range(0, u_segs):
# Initialize variables for loop */
V = v1
for X in range(0, v_segs):
# VERTEX #1 */
x1, y1, z1, n1x, n1y, n1z = sqEllipsoid(x, y, z, a1, a2, a3, U, V, n, e)
x2, y2, z2, n2x, n2y, n2z = sqEllipsoid(x, y, z, a1, a2, a3, U + dU, V, n, e)
x3, y3, z3, n3x, n3y, n3z = sqEllipsoid(x, y, z, a1, a2, a3, U + dU, V + dV, n, e)
x4, y4, z4, n4x, n4y, n4z = sqEllipsoid(x, y, z, a1, a2, a3, U, V + dV, n, e)

o.extend([COLOR, r, g, b, NORMAL, n1x, n1y, n1z, VERTEX, x1, y1, z1])
o.extend([COLOR, r, g, b, NORMAL, n2x, n2y, n2z, VERTEX, x2, y2, z2])
o.extend([COLOR, r, g, b, NORMAL, n4x, n4y, n4z, VERTEX, x4, y4, z4])
o.extend([COLOR, r, g, b, NORMAL, n2x, n2y, n2z, VERTEX, x2, y2, z2])
o.extend([COLOR, r, g, b, NORMAL, n3x, n3y, n3z, VERTEX, x3, y3, z3])
o.extend([COLOR, r, g, b, NORMAL, n4x, n4y, n4z, VERTEX, x4, y4, z4])

# Update variables for next loop */
V += dV
# Update variables for next loop */
U += dU
o.append(END)
return o

def makeSuperQuadricToroid(x, y, z, a1, a2, a3, alpha, n, e, u1, u2, v1, v2, u_segs, v_segs, color=[0.5, 0.5, 0.5]):

r, g, b = color

# Calculate delta variables */
dU = (u2 - u1) / u_segs
dV = (v2 - v1) / v_segs

o = [ BEGIN, TRIANGLES ]

U = u1
for Y in range(0, u_segs):
# Initialize variables for loop */
V = v1
for X in range(0, v_segs):
# VERTEX #1 */
x1, y1, z1, n1x, n1y, n1z = sqToroid(x, y, z, a1, a2, a3, U, V, n, e, alpha)
x2, y2, z2, n2x, n2y, n2z = sqToroid(x, y, z, a1, a2, a3, U + dU, V, n, e, alpha)
x3, y3, z3, n3x, n3y, n3z = sqToroid(x, y, z, a1, a2, a3, U + dU, V + dV, n, e, alpha)
x4, y4, z4, n4x, n4y, n4z = sqToroid(x, y, z, a1, a2, a3, U, V + dV, n, e, alpha)

o.extend([COLOR, r, g, b, NORMAL, n1x, n1y, n1z, VERTEX, x1, y1, z1])
o.extend([COLOR, r, g, b, NORMAL, n2x, n2y, n2z, VERTEX, x2, y2, z2])
o.extend([COLOR, r, g, b, NORMAL, n4x, n4y, n4z, VERTEX, x4, y4, z4])
o.extend([COLOR, r, g, b, NORMAL, n2x, n2y, n2z, VERTEX, x2, y2, z2])
o.extend([COLOR, r, g, b, NORMAL, n3x, n3y, n3z, VERTEX, x3, y3, z3])
o.extend([COLOR, r, g, b, NORMAL, n4x, n4y, n4z, VERTEX, x4, y4, z4])

# Update variables for next loop */
V += dV
# Update variables for next loop */
U += dU
o.append(END)
return o

def makeEllipsoid(x, y, z, a1, a2, a3):
return makeSuperQuadricEllipsoid(x, y, z, a1, a2, a3, 1.0, 1.0, -math.pi / 2, math.pi / 2, -math.pi, math.pi, 10, 10)

def makeCylinder(x, y, z, a1, a2, a3):
return makeSuperQuadricEllipsoid(x, y, z, a1, a2, a3, 0.0, 1.0, -math.pi / 2, math.pi / 2, -math.pi, math.pi, 10, 10)

def makeSpindle(x, y, z, a1, a2, a3):
return makeSuperQuadricEllipsoid(x, y, z, a1, a2, a3, 2.0, 1.0, -math.pi / 2, math.pi / 2, -math.pi, math.pi, 10, 10)

def makeDoublePyramid(x, y, z, a1, a2, a3):
return makeSuperQuadricEllipsoid(x, y, z, a1, a2, a3, 2.0, 2.0, -math.pi / 2, math.pi / 2, -math.pi, math.pi, 10, 10)

def makePillow(x, y, z, a1, a2, a3):
return makeSuperQuadricEllipsoid(x, y, z, a1, a2, a3, 1.0, 0.0, -math.pi, math.pi, -math.pi, math.pi, 10, 10)

def makeRoundCube(x, y, z, a1, a2, a3):
return makeSuperQuadricEllipsoid(x, y, z, a1, a2, a3, 0.2, 0.2, -math.pi / 2, math.pi / 2, -math.pi, math.pi, 10, 10)

def makeToroid(x, y, z, a1, a2, a3, alpha):
return makeSuperQuadricToroid(x, y, z, a1, a2, a3, alpha, 1.0, 1.0, -math.pi, math.pi, -math.pi, math.pi, 10, 10)

x, y, z, rx, ry, rz = 1, 1, 1, 1, 2, 3
cmd.load_cgo(makeEllipsoid(x, y, z, rx, ry, rz), 'ellipsoid-cgo')
x, y, z, rx, ry, rz = 1, 1, 1, 8, 2, 2
cmd.load_cgo(makeToroid(x, y, z, rx, ry, rz, 3), 'toroid-cgo')