Andriy Sultanov
Andriy Sultanov

Reputation: 86

Spherical interpolation between two points in GLM for OpenGL

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)?

Upvotes: 0

Views: 440

Answers (1)

Stéphane Laurent
Stéphane Laurent

Reputation: 84619

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:

  • if x1 and x2 are the endpoints of the arc, then both lsp and lep should be equal to R
  • since s1 and s2 have been normalized, the denominator in the calculation of phi is useless

Upvotes: 1

Related Questions