Solved it, rotation matrix was incorrect.
new code:
void setAngle(OBMol &mol, OBAtom * vertex, OBAtom * b, OBAtom * c, double
ang) {
vector<int> atoms;
double sn, cs, t, x, y, z, tx, ty, tz;
double m[9];
//! locates all atoms for which there exists a path to 'end'
//! without going through 'bgn'
//! children must not include 'end'
// void OBMol::FindChildren(vector<OBAtom*> &children,OBAtom *bgn,OBAtom
*end)
mol.FindChildren(atoms, vertex->GetIdx(), c->GetIdx());
atoms.push_back(c->GetIdx());
cout << "Updating: " << atoms.size() << " atoms: ";
for (int a = 0; a < atoms.size(); a++) {
cout << describe(mol.GetAtom(atoms.at(a))) << " ";
}
cout << endl;
//used later to convert system to new frame of reference when we apply
rotation matrix
vector3 vertexvec = vertex->GetVector();
vector3 bvec = b->GetVector();
vector3 cvec = c->GetVector();
// b1/c1 are "true" vectors, used for calculating angle between them.
vector3 b1 = bvec - vertexvec;
vector3 c1 = cvec - vertexvec;
//need normalized rotation axis to perform rotation.
vector3 rotationAxisU = OBAPI::cross(b1, c1);
vector3 rotationAxisN = rotationAxisU.normalize();
double dp;
dp = OBAPI::dot(b1, c1) / (b1.length() * c1.length());
double angle = acos(dp);
cout << "DOT: " << dp << endl;
cout << "current angle: " << angle << " requested: " << ang << endl;
double diffAng = ang - angle;
cout << "diff: " << diffAng << endl;
//set up rotation matrix
sn = sin(diffAng);
cs = cos(diffAng);
t = 1 - cs;
cout << "Debug: " << sn << " " << cs << " " << t << endl;
x = rotationAxisN.x();
y = rotationAxisN.y();
z = rotationAxisN.z();
m[0] = t * x * x + cs;
m[1] = t * x * y + sn * z;
m[2] = t * x * z - sn * y;
m[3] = t * x * y - sn * z;
m[4] = t * y * y + cs;
m[5] = t * y * z + sn * x;
m[6] = t * x * z + sn * y;
m[7] = t * y * z - sn * x;
m[8] = t * z * z + cs;
//rotation matrix set
tx = vertexvec.x();
ty = vertexvec.y();
tz = vertexvec.z();
//move atoms
vector<int>::iterator i;
int j;
for (i = atoms.begin(); i != atoms.end(); ++i) {
j = *i;
OBAtom * atom = mol.GetAtom(j);
vector3 tempvec = atom->GetVector();
double xtemp = tempvec.x();
double ytemp = tempvec.y();
double ztemp = tempvec.z();
xtemp -= tx;
ytemp -= ty;
ztemp -= tz;
x = xtemp * m[0] + ytemp * m[3] + ztemp * m[6];
y = xtemp * m[1] + ytemp * m[4] + ztemp * m[7];
z = xtemp * m[2] + ytemp * m[5] + ztemp * m[8];
xtemp = x;
ytemp = y;
ztemp = z;
xtemp += tx;
ytemp += ty;
ztemp += tz;
vector3 newvec(xtemp, ytemp, ztemp);
cout << "->updating atom : " << describe(atom) << " from pos : "
<< atom->GetVector() << " to pos: " << newvec
<< endl;
atom->SetVector(newvec);
}
}
--
View this message in context:
http://forums.openbabel.org/OBMol-SetAngle-code-problem-c-tp4657153p4657154.html
Sent from the openbabel-devel mailing list archive at Nabble.com.
------------------------------------------------------------------------------
CenturyLink Cloud: The Leader in Enterprise Cloud Services.
Learn Why More Businesses Are Choosing CenturyLink Cloud For
Critical Workloads, Development Environments & Everything In Between.
Get a Quote or Start a Free Trial Today.
http://pubads.g.doubleclick.net/gampad/clk?id=119420431&iu=/4140/ostg.clktrk
_______________________________________________
OpenBabel-Devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openbabel-devel