On 05/19/2011 02:00 PM, David Lonie wrote:
Hi Fabien,
On Thu, May 19, 2011 at 5:09 AM, Archambault Fabien
fabien.archambault@nanotimes.fr wrote:
I believe hte function I have to use is Avogadro.Navigate.rotate
Its help is:
rotate( (GLWidget)arg1, (object)arg2, (float)arg3, (float)arg4,
(float)arg5) → None :
Rotate about center by deltaX, deltaY, and deltaZ in the x, y and z
axes A generalization of the rotate() and tilt() methods.
That method will rotate the camera, not the molecule. To rotate the
molecule itself, you will need to manually set each atom’s position
using the Molecule.pos() and Molecule.setPos() functions (I think that
is the correct python syntax?).
There is a tutorial extension that shows how to rotate selected atoms
around an arbitrary vector – it is in C++, but should offer some help
as to how a rotation can be performed. The source code can be found in
libavogadro/examples/thirdPartyExtensions/04-RotateSelection/rotateselectionextension.cpp
of the avogadro master branch.
The function that actually performs the rotation is here:
avogadro/libavogadro/examples/thirdPartyExtensions/04-RotateSelection/rotateselectionextension.cpp at master · cryos/avogadro · GitHub
The key bits are:
Eigen::AngleAxis rot (angle * DEG_TO_RAD, axis.normalized());
This essentially constructs a rotation matrix ‘rot’ using the
Eigen::AngleAxis transform from an angle and axis vector.
Then it’s a matter of iterating through the atoms and applying the rotation:
for (int i = 0; i< selected.size(); i++) {
atom = qobject_cast<Atom*>(selected.at(i));
// you'll probably want 'atom = mymolecule.atoms().at(i)' in your app
// instead of the above line
coord = *atom->pos(); // extract coordinate
coord -= offset; // Optional: offset the rotation axis
coord = rot * coord; // Apply rotation
coord += offset; // reset offset
atom->setPos(coord); // Set new coordinate
}
Hope this helps,
Dave
Hi,
thanks for this reply.
I did not notice that it was for the camera. This explains the widget…
I tried to look at the code but I do not “speak” C++ so I believe I will
have a hard time to understand… The main problem, for me, is that the
class setPos does not exists in the python binding.
Here are all the available classes for the atom object (in python) :
for atom in mol.atoms:
print atom.
atom.class atom.init atom.sizeof
atom.forceVector atom.pos
atom.delattr atom.module atom.str
atom.formalCharge atom.residue
atom.dict atom.new atom.subclasshook
atom.id atom.residueId
atom.doc atom.reduce atom.weakref
atom.index atom.type
atom.format atom.reduce_ex atom.atomicNumber
atom.isHydrogen atom.update
atom.getattribute atom.repr atom.bond
atom.neighbors atom.valence
atom.hash atom.setattr atom.bonds
atom.partialCharge
The pos works but not the setPos.
My trial is on a water molecule (h2o.xyz):
$ python
import Avogadro as a
mol = a.MoleculeFile.readMolecule(‘h2o.xyz’)
for atom in mol.atoms:
… print atom.pos
…
[ 0.00369 2.73505 2.63908]
[-0.88715 2.29885 2.66616]
[-0.14964 3.67132 2.43027]
Perhaps this is somewhere else?
I also tried something I believed it should work but it did not move the
atoms:
mol.center
array([-0.34436667, 2.90174 , 2.57850333])
mol.translate(-mol.center)
mol.center
array([ 5.55111512e-17, -1.48029737e-16, 4.44089210e-16])
for atom in mol.atoms:
… print atom.pos
…
[ 0.34805667 -0.16669 0.06057667]
[-0.54278333 -0.60289 0.08765667]
[ 0.19472667 0.76958 -0.14823333]
The center seems to have moved but no atoms really moved…
If someone knows how to use python bindings in Avogadro and done some
tutorials it should be nice.
Fabien