Hi,
I'm new to OpenSCAD's animation feature, and I'm playing around with
some simple animation scripts. Generally, it's very useful, however,
I'm running into a fairly annoying problem.
I started with this guide
(https://www.instructables.com/id/Animating-with-OpenSCAD/) which
recommended wrapping your use of lookup() in a function like:
loc = [
[0,0,0], // initial position
[0,0,0], // top body shifts over slightly
[0,0,10], // lifts leg up
[0,5,10], // moves leg forward
[0,5,0], // puts leg down
[0,5,0], // puts leg down
[0,5,0], // puts leg down
[0,5,0], // puts leg down
[0,5,0], // puts leg down
[0,5,0], // puts leg down
];
function xyz(t,i) = lookup(t, [
[0/len(loc),loc[0][i]],
[1/len(loc),loc[1][i]],
[2/len(loc),loc[2][i]],
[3/len(loc),loc[3][i]],
[4/len(loc),loc[4][i]],
[5/len(loc),loc[5][i]],
[6/len(loc),loc[6][i]],
[7/len(loc),loc[7][i]],
[8/len(loc),loc[8][i]],
[9/len(loc),loc[9][i]],
[10/len(loc),loc[10][i]],
]);
Then you can animate something by simply plugging in a call to
xyz($t, <0|1|2>) inside a translate or rotate statement.
Yet, as you can see, this violates the DRY rule, and makes for some
very tedious and unnecessary code. For every new step added to my
loc array, I need to add an entry to the array inside my xyz()
function as well.
Is there any way to rewrite my xyz() function to generate the array
on demand so I don't have to maintain what are effectively duplicate
arrays? Is a more efficient way to do this that I'm not seeing?
You don't need to use lookup at all. Just work out the two indices of loc
that t will select a point between and then use linear
interpolation between those two points. That is what lookup does.
Or you could use list comprehension for loop to make the list to pass to
lookup.
I don't think you need to pass i because lookup should be able to
interpolate vectors.
On Fri, 6 Mar 2020 at 22:47, Chris Spencer chrisspen@gmail.com wrote:
Hi,
I'm new to OpenSCAD's animation feature, and I'm playing around with
some simple animation scripts. Generally, it's very useful, however,
I'm running into a fairly annoying problem.
I started with this guide
(https://www.instructables.com/id/Animating-with-OpenSCAD/) which
recommended wrapping your use of lookup() in a function like:
loc = [
[0,0,0], // initial position
[0,0,0], // top body shifts over slightly
[0,0,10], // lifts leg up
[0,5,10], // moves leg forward
[0,5,0], // puts leg down
[0,5,0], // puts leg down
[0,5,0], // puts leg down
[0,5,0], // puts leg down
[0,5,0], // puts leg down
[0,5,0], // puts leg down
];
function xyz(t,i) = lookup(t, [
[0/len(loc),loc[0][i]],
[1/len(loc),loc[1][i]],
[2/len(loc),loc[2][i]],
[3/len(loc),loc[3][i]],
[4/len(loc),loc[4][i]],
[5/len(loc),loc[5][i]],
[6/len(loc),loc[6][i]],
[7/len(loc),loc[7][i]],
[8/len(loc),loc[8][i]],
[9/len(loc),loc[9][i]],
[10/len(loc),loc[10][i]],
]);
Then you can animate something by simply plugging in a call to
xyz($t, <0|1|2>) inside a translate or rotate statement.
Yet, as you can see, this violates the DRY rule, and makes for some
very tedious and unnecessary code. For every new step added to my
loc array, I need to add an entry to the array inside my xyz()
function as well.
Is there any way to rewrite my xyz() function to generate the array
on demand so I don't have to maintain what are effectively duplicate
arrays? Is a more efficient way to do this that I'm not seeing?
OpenSCAD mailing list
Discuss@lists.openscad.org
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
I don't think you need to pass i because lookup should be able to
interpolate vectors.
It would be nice but lookup only accepts numbers in the table.
Is there any way to rewrite my xyz() function to generate the array
on demand so I don't have to maintain what are effectively duplicate
arrays? Is a more efficient way to do this that I'm not seeing?
You may try this:
function xyz(loc,t) =
t<0 || t>1 ? echo("xyz: t out of range") undef
:
let( s = t*(len(loc)-1),
k = floor(s) )
(1-s+k)*loc[k] + (s-k)*loc[k+1];
that returns the interpolated position from table loc.
My previous code of xyz() has a bug: it returns undef when t=1. Here is a
correction:
function xyz(loc,t) =
t<0 || t>1 ? echo("xyz: t out of range") undef
:
let( s = t*(len(loc)-1),
k = floor(s) )
k<len(loc)-1? (1-s+k)*loc[k] + (s-k)*loc[k+1]: loc[k];
Em seg., 9 de mar. de 2020 às 16:22, Ronaldo Persiano rcmpersiano@gmail.com
escreveu:
I don't think you need to pass i because lookup should be able to
interpolate vectors.
It would be nice but lookup only accepts numbers in the table.
Is there any way to rewrite my xyz() function to generate the array
on demand so I don't have to maintain what are effectively duplicate
arrays? Is a more efficient way to do this that I'm not seeing?
You may try this:
function xyz(loc,t) =
t<0 || t>1 ? echo("xyz: t out of range") undef
:
let( s = t*(len(loc)-1),
k = floor(s) )
(1-s+k)*loc[k] + (s-k)*loc[k+1];
that returns the interpolated position from table loc.