# Module to create and interpolate sort of splines. # Last edited on 2021-06-08 13:12:04 by jstolfi # A /sploine/ is a specific representation of a curve in some # {n}-dimensional space by discrete samples. It is hereinafter defined # as a list of /states/, where each state is a triple {(u,t,f)}, {u} and # {t} are float lists or tuples of the same length {n}, and {f} is an # integer /fixation/ flag. # # The vector {u} is the {position} of the state, and {t} is supposed to # be the corresponding {tangent} vector: the derivative of {u} with # respect to some curve parametrization, normalized to unit length. The # {f} flag is relevant when smoothing the curve; see # {sploine_smooth.relax_curves}. # # A state can also be {None} to signify a gap (zero-order discontinuity) # in the curve. The {None}s break the sploine into /sections/, which, # through the {interpolate} function, represent independent curves that # are continuous to first order. # # The points between two consecutive states {sta,stb} that are not # {None} are supposed to be filled with a continuous arc of curve by the # {sploine_arc;interpolate} procedure. The interpolated arc starts and ends # with the positions of {sta} and {stb}, and the derivatves of the # position at those points are multiples of the respective tangent # vectors. import sploine_IMP def interpolate(r, sta, stb): # Interpolates one state {str} between {n}-dimensional states {sta} # and {stb} at parameter value {r}. The states must not be {None} and # their velocities must not be {None}. As {r} goes from 0 to 1, the # reurned state {strr} will go from {sta} to {stb}. Except for these # two values, the will have the fixation flag of the result will be 0. return sploine_IMP.interpolate(r, sta, stb) def interpolate_many(sta, stb, ds): # Interpolates one or more sample states between {n}-dimensional # states {sta} (inclusive) and {stb} (exclusive), which must not be # {None}. The spacing of the states will be about {ds} in {n}-space. # # Returns the list {STS} of interpolated states, which is a sploine # with a single section. The first element of {STS} will always be be # {sta}. The other samples, if any, will have fixation flag set to 0. return sploine_IMP.interpolate_many(sta, stb, ds) def acceleration(sta,stb): # Returns an estimate of the mean acceleration {A''(r)} in the # arc with endstates {sta,stb}. return sploine_IMP.acceleration(sta,stb) def arc_length(sta, stb): # Returns an estimate of the total length of the arc with endstates {sta,stb}. # Currently not very accurate. return sploine_IMP.arc_length(sta, stb) # TOOLS FOR TESTING def circle_example_states(ang, R): # Returns an arbitrary pair of states that describes an arc of circle # with radius {R} that spans {ang} radians. If {ang} is zero, {R}must be # {+inf}, and then the procedure returns two states that define a straight # line segment. return sploine_IMP.circle_example_states(ang, R) def check_circle_like(sta,stb): # Checks whether the arc defined by the endstates {sta,stb} is an arc of # circle. Bombs out if not. return sploine_IMP.check_circle_like(sta,stb) def example_curves(n): # Generates a sploine in {n}-space with multiple sections, fixed and # semi-fixed states, etc. The dimension {n} must be at least 3. Each # state describes a sphere: the first three coordinates are {X,Y,rad} # with {X,Y} in the hundreds range, {rad} about 5. and all the other # attributes in {[0,1]}. return sploine_IMP.example_curves(n)