Ellipsoid: Difference between revisions
		
		
		
		
		
		Jump to navigation
		Jump to search
		
				
		
		
	
| mNo edit summary | No edit summary | ||
| (2 intermediate revisions by 2 users not shown) | |||
| Line 1: | Line 1: | ||
| This script provides  | This script provides methods that create [[cgo]]s as triangles. It uses code that is ported from [http://www.gamedev.net/reference/articles/article1172.asp this c++ code] and seems to be correct!   | ||
| Here is the script. The last four lines show this in use, by making  | 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'. | ||
| <source lang="python"> | <source lang="python"> | ||
| from pymol. | from pymol.cgo import BEGIN, COLOR, TRIANGLES, VERTEX, NORMAL, END | ||
| from pymol import cmd | from pymol import cmd | ||
| Line 22: | Line 21: | ||
|          return signOfFloat(math.sin(v)) * math.pow(math.fabs(math.sin(v)), n) |          return signOfFloat(math.sin(v)) * math.pow(math.fabs(math.sin(v)), n) | ||
| def sqEllipsoid(a1, a2, a3, u, v, n, e): | def sqEllipsoid(x, y, z, a1, a2, a3, u, v, n, e): | ||
|          x = a1 * sqC(u, n) * sqC(v, e) |          x = a1 * sqC(u, n) * sqC(v, e) + x | ||
|          y = a2 * sqC(u, n) * sqS(v, e) |          y = a2 * sqC(u, n) * sqS(v, e) + y | ||
|          z = a3 * sqS(u, n) |          z = a3 * sqS(u, n) + z | ||
|          nx = sqC(u, 2 - n) * sqC(v, 2 - e) / a1 |          nx = sqC(u, 2 - n) * sqC(v, 2 - e) / a1 | ||
|          ny = sqC(u, 2 - n) * sqS(v, 2 - e) / a2 |          ny = sqC(u, 2 - n) * sqS(v, 2 - e) / a2 | ||
| Line 31: | Line 30: | ||
|          return x, y, z, nx, ny, nz |          return x, y, z, nx, ny, nz | ||
| def sqToroid(a1, a2, a3, u, v, n, e, alpha): | def sqToroid(x, y, z, a1, a2, a3, u, v, n, e, alpha): | ||
|          a1prime = 1 / (a1 + alpha) |          a1prime = 1.0 / (a1 + alpha) | ||
|          a2prime = 1 / (a2 + alpha) |          a2prime = 1.0 / (a2 + alpha) | ||
|          a3prime = 1 / (a3 + alpha) |          a3prime = 1.0 / (a3 + alpha) | ||
|          x = a1prime * sqCT(u, e, alpha) * sqC(v, n) |          x = a1prime * sqCT(u, e, alpha) * sqC(v, n) | ||
|          y = a2prime * sqCT(u, e, alpha) * sqS(v, n) |          y = a2prime * sqCT(u, e, alpha) * sqS(v, n) | ||
| Line 43: | Line 42: | ||
|          return x, y, z, nx, ny, nz |          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 */ |                          # Update variables for next loop */ | ||
|                          U += dU |                          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  |                  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 = 1, 1, 1 | x, y, z, rx, ry, rz = 1, 1, 1, 1, 2, 3 | ||
| cmd.load_cgo(makeEllipsoid(x, y, z, rx, ry, rz), 'ellipsoid-cgo') | |||
| cmd. | x, y, z, rx, ry, rz = 1, 1, 1, 8, 2, 2 | ||
| x, y, z  | cmd.load_cgo(makeToroid(x, y, z, rx, ry, rz, 3), 'toroid-cgo') | ||
| rx, ry, rz =  | |||
| cmd. | |||
| </source> | </source> | ||
| [[Category:Script_Library|Ellipsoid]] | |||
| [[Category:Math_Scripts]] | |||
Latest revision as of 08:51, 30 April 2009
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')