| 1 | #
|
|---|
| 2 | # Example code to rotate atoms about a specified line.
|
|---|
| 3 | #
|
|---|
| 4 | # Center is a point on the line (3-tuple) and direction is a vector parallel
|
|---|
| 5 | # to the line (3-tuple), both being in global coordinates (not molecule
|
|---|
| 6 | # coordinates). Angle is in degrees.
|
|---|
| 7 | #
|
|---|
| 8 | def rotate_atoms(atoms, center, direction, angle):
|
|---|
| 9 |
|
|---|
| 10 | cx, cy, cz = center
|
|---|
| 11 | dx, dy, dz = direction
|
|---|
| 12 |
|
|---|
| 13 | # Transform rxf shifts center to (0,0,0), rotates about (0,0,0),
|
|---|
| 14 | # then translates (0,0,0) back to center.
|
|---|
| 15 | from chimera import Xform
|
|---|
| 16 | rxf = Xform.translation(-cx,-cy,-cz)
|
|---|
| 17 | rxf.premultiply(Xform.rotation(dx,dy,dz,angle))
|
|---|
| 18 | rxf.premultiply(Xform.translation(cx,cy,cz))
|
|---|
| 19 |
|
|---|
| 20 | # Precompute transforms from global to molecule coordinates.
|
|---|
| 21 | mols = set(a.molecule for a in atoms)
|
|---|
| 22 | mxf = dict((m, m.openState.xform.inverse()) for m in mols)
|
|---|
| 23 |
|
|---|
| 24 | # Apply rotation to global atom coordinate then transform to molecule
|
|---|
| 25 | # coordinates and set new atom position.
|
|---|
| 26 | for a in atoms:
|
|---|
| 27 | a.setCoord(mxf[a.molecule].apply(rxf.apply(a.xformCoord())))
|
|---|
| 28 |
|
|---|
| 29 | #
|
|---|
| 30 | # Test
|
|---|
| 31 | #
|
|---|
| 32 | from chimera import selection
|
|---|
| 33 | atoms = selection.currentAtoms()
|
|---|
| 34 | rotate_atoms(atoms, (1,2,3), (1,1,0), 45)
|
|---|