Hello,
I have a problem, more mathematical than computational, to solve, but I have not been able to solve it myself until now ...
I have a set of 3 atoms connected to each other forming an angle X between the bond. I need to implement a code that when X is not equal to 109.4 I transform one of the atoms of the end so that this angle is equal to 109.4.
Here is a more detailed example:
The 3 atoms are in the 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 find the point O1 'so that the angle between the vectors is 109.45 °, all this without changing the Euclidean distance, that is, the distance of C1O1 is equal to the distance of C1O1 '.
Here are two images to make it easier to understand:
My problem is that I can not figure out the dot (?,?,?) in a mathematical way. The only way I could solve it was by implementing a code that searches the position of the point randomly, but my goal was a real-time response ...
There is some mathematical calculation that based on the input data points C1, O5, O1 and the initial and final angles, tell me what has to be the point O1 '??????
The following is the python script I used to generate the value, but I believe there is some general mathematical way to solve it: I do not know what 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