#### Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

# quat.fromToRotation with opposite vectors

edited November 2020 in Bugs Posts: 509

I've posted this on the issue tracker, but I no longer have a bitbucket login so can't keep up with it.

``````quat.fromToRotation(vec3(1,0,0), vec3(-1,0,0))
``````

returns the identity rotation. Rather, it should return a rotation that achieves the goal of rotating `vec3(1,0,0)` to `vec3(-1,0,0)`. Such a rotation is not unique, but they do exist so all that is needed is some way of choosing one out of the ones that work.

My code for this (in the pre-quat days when I used a `vec4`) was:

``````function (u,v)
if v:cross(u):len() < tolerance then
if v:dot(u) >= -tolerance then
return vec4(1,0,0,0)
end
u = u:normalize()
local a,b,c = abs(u.x), abs(u.y), abs(u.z)
if a < b
and a < c then
v = vec3(0,-u.z,u.y)
elseif b < c then
v = vec3(u.z,0,-u.x)
else
v = vec3(u.y,-u.x,0)
end
else
u = u:normalise()
v = u + v:normalise()
end
v = v:normalise()
local d = u:dot(v)
u = u:cross(v)
return vec4(d,u.x,u.y,u.z)
end
``````

(`tolerance` was to say that the two vectors don't have to be exactly opposite for this to kick in so that I didn't run in to very small numbers in the arithmetic.)

Tagged:

Posts: 5,613

Thanks for reporting the issue @LoopSpace — this is our implementation of fromToRotation

``````        auto fromToRotation = [] (glm::vec3 u, glm::vec3 v)
{
u = glm::normalize(u);
v = glm::normalize(v);
glm::quat q;
glm::vec3 a = glm::cross(u,v);
q.x = a.x;
q.y = a.y;
q.z = a.z;
float len = glm::length(u) * glm::length(u) * glm::length(v) * glm::length(v);
q.w = std::sqrtf(len) + glm::dot(u, v);
return glm::normalize(q);
};
``````

I can see it has problems, will try updating it with yours