8
Hello,
I have a problem, more mathematical than computational, to solve, but I haven’t been able to solve it myself until now...
I have a set of three atoms connected to each other forming an angle X between the bond. I need to implement a code that when X does not equal 109.4 I transform one of the end atoms so that this angle equals 109.4.
Here is a more detailed example:
the 3 atoms are in space R3. I have their position for example:
O5 = 12,350,5,420,12,480 C1 = 13.290,4.510,13.090 O1 = 14,461,5.261,13.253
I know that the angle between the vectors C1O5 and C1O1 is 104,808°
And my goal is to know how I do to discover the point O1' so that the angle between the vectors is 109.45°, all without changing the Euclidean distance, ie the distance of C1O1 is equal to the distance of C1O1'.
Follow two images to facilitate understanding:
My problem is that I can’t figure out the point (?,?,?) in a mathematical way. The only way I could solve it was by implementing a code that looks for the position of the spot randomly, but my goal was a real-time response...
Is there any mathematical calculation that based on the input data of points C1, O5, O1 and the initial and final angles, tell me which has to be point O1'??????
Below is the python script that I used to generate the value, but I believe that there is some generic mathematical form to solve just don’t know which is =(
import biopyVector as bp
import math
import numpy
import random
O5 = bp.Vector(12.350,5.420,12.480)
C1 = bp.Vector(13.290,4.510,13.090)
O1 = bp.Vector(14.461,5.261,13.253)
angulo = bp.calc_angle(O5, C1, O1)
print "Angulo Atual: " + str(math.degrees(angulo))
distanciaC1O1 = bp.dist2(C1,O1)
print "Distancia Atual: " + str(distanciaC1O1)
while(True):
O1linha = bp.Vector(O1[0],random.uniform((C1[1]-2), (C1[1]+2)),random.uniform((C1[2]-2), (C1[2]+2)))
angulo = math.degrees(bp.calc_angle(O5, C1, O1linha))
distanciaC1O1linha = bp.dist2(C1,O1linha)
if(angulo >= 109.4) and (angulo <= 109.5):
if(distanciaC1O1linha >= (distanciaC1O1-0.01)) and (distanciaC1O1linha <= (distanciaC1O1+0.01)):
print "Angulo Novo: " + str(angulo)
print O1linha
break
If you always have 3 non-colleger points, you can use one of them as the source (e.g., C1) and you have the two linearly independent vectors u=C1O1 and v=C1O5. Just use the vector product between them to find a vector w and form a base for R3. Then you apply the rotation matrix to rotate around w by the angle you want.
– Sigur