Advertisement

Interpolation of Vectors

Started by November 14, 2002 08:18 AM
5 comments, last by LilBudyWizer 22 years, 3 months ago
I''m setting up some vector template classes and one type of function it seems worthwhile to add is interpolation between two vectors. Basically the function will take a vector and a scalar between 0 and 1. 0 produces the original vector and 1 produces the vector parameter. I can think of four ways of doing that. One is interpolating just the magnitude and similarly the second is interpolating just the direction neither of which causes 1 to produce the vector parameter. The third is if the function call is v1.interp(v2,t) then it returns v1+(v2-v1)*t which produces a set of vectors terminating in a straight line. The fourth interpolates both the direction and magnitude but produces a curve instead of line since it is a linear interpolation of the direction. So is there a fifth or sixth way to interpret the parameters in the context of interpolation? Additionally since each of these take the same parameters overloading the functions isn''t an option. It seems that unless one or more of these are completely useless there would be standard names for the operations. Anyone have any suggestions on what to call this functions?
Keys to success: Ability, ambition and opportunity.
I decided that it isn''t really an interpolation unless 0 produces the original vector and 1 produces the second. So I dropped the two where that wouldn''t be true. Providing the functions would be less efficient anyway. Each step you either need two square roots or two atan2 calls to get the values you are interpolating between. It would be better to just get the magnitude or theta once for each and then set it incrementally. The same arguement can be made for the fourth way since it is a linear interpolation of the polar components, but the vector is stored as rectangular components. I might create a seperate polar vector where the components are stored as polar components. A polar vector just seems so useless though since ultimately you need a rectangular vector.
Keys to success: Ability, ambition and opportunity.
Advertisement
You could try slerping (spherical interpolation). If the vector''s are both unit length...

t = 0...1 interpolation value.

theta = acos(v1 DOT v2)
v3 = v1 * (sin((1-t)*theta)/sin(theta) +
v2 * (sin(t*theta)/sin(theta))


That''s a neat function. It seems a lot easier than taking the cross product to get an axis of rotation and then using it to rotate the vector. I must admit I don''t quite follow why it works though.
Keys to success: Ability, ambition and opportunity.
A more robust implementation of vector slerp would be:


  // Avoid use of acosfloat angle, dot = Dot(a, b);if (dot < 0)   angle = PI - 2 * asin(Magnitude(-b - a) / 2)else   angle = 2 * asin(Magnitude(b - a) / 2)// Re-arrange to use the more robust sinc functionv = (a * sinc((1 - t) * angle) * (1 - t) + b * sinc(t * angle) * t) * (1 / sinc(angle))  


A robust version of sinc also is:


  // Try not to use sin for as far away from 1 as is practicalif (1 + x * x == 1)   sinc = 1else   sinc = sin(x) / x  
What do you mean by "more robust"?
Keys to success: Ability, ambition and opportunity.
Advertisement
Sorry, I should have posted the source:

http://www.hadron.org/~hatch/rightway.php

This topic is closed to new replies.

Advertisement