matrix interpolation

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view

matrix interpolation


[ Mostly this is just me nattering about some stuff I was playing with, with a minor wish list item tossed in.  I'd be interested in any hints on how to do this better; I recognize that this is stuff that some of you probably do in your sleep. ]

I started to play with animation, and it seemed like one of the key things that would be useful would be to conveniently interpolate between two (or N) positions or rotations.  That is, I'd like to say:

When $t is 0, the position is [x1,y1,z1].
When $t is 0.5, the position is [x2,y2,z2].
When $t is 1.0, the position is [x3,y3,z3].
... with interpolation for points between.

Hey, lookup( ) does interpolation like that:

t1 = [
    [ 0, 1 ],
    [ 1, 2 ]

echo(lookup(0.5, t1));

ECHO: 1.5

Interpolation is just addition, subtraction and multiplication, and OpenSCAD knows how to do subtraction and multiplication on matrices, right?

p1 = [0,0,0];
p2 = [1,2,3];
p15 = p1 + (p2-p1)*0.5;

ECHO: [0.5, 1, 1.5]

So lookup( ) should be able to do similar interpolation, right?

t2 = [
    [ 0, [0,0,0] ],
    [ 1, [1,2,3] ]

echo(lookup(0.5, t2));

ECHO: undef


Very minor wish list:  make lookup do this.

I did put together a function that rearranges such a table into three tables and then uses lookup:

function xyzinterp(v, table) =
    let (x = [for (i = [ 0:len(table)-1 ]) [ table[i][0], table[i][1][0]] ])
    let (y = [for (i = [ 0:len(table)-1 ]) [ table[i][0], table[i][1][1]] ])
    let (z = [for (i = [ 0:len(table)-1 ]) [ table[i][0], table[i][1][2]] ])
        [ lookup(v, x), lookup(v, y), lookup(v,z) ];

(extrapolation to arbitrary dimensionality left as an exercise for the reader) and using that I built a couple of modules:
module atranslate(table) {
    translate(xyzinterp($t, table)) children();

module arotate(table) {
    rotate(xyzinterp($t, table)) children();
so that you can give a table of positions/rotations and it'll animate them.

Since animations are loops, it seems likely that a common case would be to start at one position, move to another position at $t=0.5, and then return to the original position:
module a2translate(p1, p2) {
    atranslate([[0.05, p1], [0.45, p2], [0.55, p2], [0.95, p1]]) children();
module a2rotate(p1, p2) {
    arotate([[0.05, p1], [0.45, p2], [0.55, p2], [0.95, p1]]) children();

and using them I took one of my models and combined the "render assembled" and "render for printing" sequences into one animation sequence that moved the parts back and forth between the two layouts.

And that's what I've been doing this morning instead of real work :-)

OpenSCAD mailing list
[hidden email]