in reply to Re^2: How to smooth values of an x,y,z array using Math::Spline
in thread How to smooth values of an x,y,z array using Math::Spline
But, if you really want the Bezier, and thus not hitting most of the points you list:
use FindBin; use local::lib "$FindBin::Bin/tmplib"; use warnings; use strict; use feature ':5.10'; my @accel = ([-0.7437,0.1118,-0.5367], [-0.5471,0.0062,-0.6338], [-0.6437,0.1216,-0.5255], [-0.4437,0.3216,-0.3255], # add three more observations, to show it works with more + than 4 points (with any 3N+1) [-0.2718,0.3142,-0.1618], [-0.4567,0.1234,+0.1618], [-0.9876,0.5432,+0.3162], ); # note: I changed from an array whose only element is an arrayref +of arrayrefs to an array who has n arrayrefs, to be a simple 2D array use Math::Spline; die "requires 3N+1 points, supplied ".scalar(@accel)." points" unless +1 == scalar(@accel) % 3; my $first = 0; my @interp_accel = (); my $NSTEPS = 100; my $dt = 1/$NSTEPS; my $grp = 0; while($first+3 < @accel) { my (@idx) = map {$first+$_} 0..3; my $t = @interp_accel ? $dt : 0; while($t < 1+$dt) { my @m = ( (1-$t)**3, (1-$t)**2 * ($t)**1 * 3, (1-$t)**1 * ($t)**2 * 3, ($t)**3 ); my $x = 0; $x += $m[$_] * $accel[$idx[$_]][0] for 0..3; my $y = 0; $y += $m[$_] * $accel[$idx[$_]][1] for 0..3; my $z = 0; $z += $m[$_] * $accel[$idx[$_]][2] for 0..3; printf "interpolate t=%.3f => [%+-7.4f,%+-7.4f,%+-7.4f]\n", $g +rp+$t, $x, $y, $z if $t<=2*$dt or $t>=$dt*($NSTEPS-2); # debug print print "...\n" if $t==3*$dt; push @interp_accel, [$x,$y,$z]; $t += $dt; } ++$grp; $first += 3; }
output:
interpolate t=0.000 => [-0.7437,+0.1118,-0.5367] interpolate t=0.010 => [-0.7379,+0.1087,-0.5396] interpolate t=0.020 => [-0.7323,+0.1057,-0.5423] ... interpolate t=0.980 => [-0.4553,+0.3097,-0.3374] interpolate t=0.990 => [-0.4496,+0.3156,-0.3315] interpolate t=1.000 => [-0.4437,+0.3216,-0.3255] interpolate t=1.010 => [-0.4387,+0.3213,-0.3205] interpolate t=1.020 => [-0.4338,+0.3209,-0.3155] ... interpolate t=1.980 => [-0.9562,+0.5187,+0.3067] interpolate t=1.990 => [-0.9718,+0.5308,+0.3115] interpolate t=2.000 => [-0.9876,+0.5432,+0.3162]
Whether this or Re^2: How to smooth values of an x,y,z array using Math::Spline is better for "smoothing" the data that you have is really up to you.
addenda: Please note that in all of my solutions, @interp_accel will contain the complete list of interpolated values, even if my manual editing or in-code logic doesn't print them all. I just skipped most of the printing to save space in the posts, so the reduced output was enough to show what was going on.
|
|---|