I'm trying to interpolate between two points on a sphere to make a simple camera following an arc. Quaternions are utterly incomprehensible to me, so I've been trying to hack something together through trial and error.
Here's the gist of the code:
glm::vec3 camera_start_pos = {-0.282546, 1.525186, -2.946500};
glm::vec3 camera_end_pos = {-2.086190, 1.957833, 1.466586};
camera_pos_start_q = glm::rotation(camera_start_pos, vec3(1,1,1));
camera_pos_end_q = glm::rotation(camera_end_pos, vec3(1,1,1));
float cur_time = (sin(glfwGetTime())+1.f)/2.f;
auto pos_slerp = glm::slerp(camera_pos_start_q, camera_pos_end_q, cur_time);
camera_pos = pos_slerp * vec3(1,1,1);
view = glm::lookAt(camera_pos,
camera_pos + camera_front,
camera_up);
This code does produce some interpolated movement, but not between the positions I want to.
What vectors do I need to use in the calls to glm::rotation
to get the right quaternions? What do i need to multiply pos_slerp
by to interpolate between camera_start_pos
and camera_end_pos
?
Is there a way to interpolate between these two points in an arc-like manner without quaternions (or including some spline library)?
I don't now the library you use but here is the method.
// x1: starting point of the arc
// x2: ending point of the arc
// cp: center of the arc
// R: radius of the arc
// t: interpolating value, between 0 and 1
// compute vectors from center to starting/ending point
// (these are coordinate-wise subtractions)
sp = x1 - cp
ep = x2 - cp
// compute the lengths of these vectors
lsp = sqrt(sum(sp^2))
lep = sqrt(sum(ep^2))
// scale the vectors
s1 = lep * sp
s2 = lsp * ep
// compute the common length of s1 and s2
l = sqrt(sum(s1^2))
// normalize s1 and s2
s1 = s1 / l
s2 = s2 / l
// compute angle between s1 and s2
phi = acos(sum(s1 * s2)/(sqrt(sum(s1^2)) * sqrt(sum(s2^2))))
// slerp
slerp = cp + R * (sin((1-t)*phi)/sin(phi) * s1 + sin(t*phi)/sin(phi) * s2)
I found this method in a R package and I have to say I don't understand everything:
x1
and x2
are the endpoints of the arc, then both lsp
and lep
should be equal to R
s1
and s2
have been normalized, the denominator in the calculation of phi
is useless