Creative Communities of the World Forums

The peer to peer support community for media production professionals.

Activity Forums Adobe After Effects Expressions multidimensional array – simple maths stuff?

  • multidimensional array – simple maths stuff?

    Posted by Frank Mansfield on March 7, 2022 at 10:21 am

    <div>Hi!</div>

    I’m trying to make a sort of super-simple loopOut(continue) expression that works on shape layers. I’m basically taking the points and tangents information from the end keyframe and from one frame before that and then adding the difference back onto the original end value (multiplied by how many frames past the end key frame we are).

    My issue is that when I try to subtract one array from the other I get an error stating “array piece can’t expand to more than one value”.

    I’m guessing this is because the shape info is stored in a multidimensional array? I suppose I could for-loop my way through it, but this seems a bit clumsy. Is there any cleaner way of adding and subtracting multidimensional arrays?

    Also – just out of interest – am I using the right terminology here? Is it a multidimensional array or a multidimensional *vector*? Is a multidimensional vector even a thing?

    Cheers!
    -f

    P.S. If my rambling, clear-as-mud message hasn’t already made this abundantly clear, I’m not particularly good at expressions. Please do not worry about underestimating my idiocy when replying… 😉

    Frank Mansfield replied 4 years, 4 months ago 2 Members · 5 Replies
  • 5 Replies
  • Frank Mansfield

    March 7, 2022 at 11:09 am

    just realised i never included the expression as it stands, sorry!

    something like this, but without the unnecessary clunk

    if ( numKeys > 0 && time > key(numKeys).time) {
    //continue out
    keyframeTime = key(numKeys).time;
    offsetKeyframeTime = key(numKeys).time - framesToTime(1);
    framesMultiplier = timeToFrames(time - keyframeTime);
    endingPointsArray = thisProperty.points(keyframeTime);
    preEndingPointsArray = thisProperty.points(offsetKeyframeTime);
    endingInTangentsArray = thisProperty.inTangents(keyframeTime);
    preEndingInTangentsArray = thisProperty.inTangents(offsetKeyframeTime);
    endingOutTangentsArray = thisProperty.outTangents(keyframeTime);
    preEndingOutTangentsArray = thisProperty.outTangents(offsetKeyframeTime);
    pointsArray = [];
    inTangentsArray = [];
    outTangentsArray = [];
    for (i=0 ; i<endingPointsArray.length ; i++) {
    pointsArray[i] = endingPointsArray[i] + (framesMultiplier * ( endingPointsArray[i] - preEndingPointsArray[i] ));
    inTangentsArray[i] = endingInTangentsArray[i] + (framesMultiplier * ( endingInTangentsArray[i] - preEndingInTangentsArray[i] ));
    outTangentsArray[i] = endingOutTangentsArray[i] + (framesMultiplier * ( endingOutTangentsArray[i] - preEndingOutTangentsArray[i] ));
    }
    pathClosedState = thisProperty.isClosed();
    createPath( points = pointsArray , inTangents = inTangentsArray , outTangents = outTangentsArray , isClosed = pathClosedState);
    }
    else value
  • Filip Vandueren

    March 7, 2022 at 11:40 am

    Hi Frank, al that’s needed is to change the last line into:

    else { value }

    1-line else statements are buggy in the new Javascript engine, so it’s best to avoid them.

    But the code works for me as is

  • Frank Mansfield

    March 7, 2022 at 11:56 am

    Cheers Filip – I’ll switch that out, thanks for the heads-up!

    What I was chasing up was whether there was a simpler way of subtracting/adding the multidimensional arrays together. Having to for-loop through seems a bit long-winded – I figured there might be a way of just subtracting one array from another? A sort of “sub (arr1 , arr2)” that works multi-dimensionally?

    Thanks dude!
    -f

  • Filip Vandueren

    March 7, 2022 at 12:05 pm

    Oops, I think I misunderstood your question, Frank.

    You already got it working with a for loop (I thought you were asking why your expression wasn’t working, but it was)

    But you are wondering if there’s another way to work through these arrays.

    Here’s a version that uses Array.map() and arrow functions to make manipulated copies of arrays:

    if ( numKeys > 0 && time > key(numKeys).time) {

    //continue out

    keyframeTime = key(numKeys).time;

    offsetKeyframeTime = keyframeTime - framesToTime(1);

    framesMultiplier = timeToFrames(time - keyframeTime);

    pointsArray = thisProperty.points();

    deltaPoints = pointsArray.map( (el, ind) => sub(el,thisProperty.points(offsetKeyframeTime)[ind]) );

    inTangentsArray = thisProperty.inTangents();

    deltaInTangents = inTangentsArray.map( (el, ind) => sub(el,thisProperty.inTangents(offsetKeyframeTime)[ind]) );

    outTangentsArray = thisProperty.outTangents();

    deltaOutTangents = outTangentsArray.map( (el, ind) => sub(el,thisProperty.outTangents(offsetKeyframeTime)[ind]) );

    pointsArray = pointsArray.map( (el, ind) => el + mul(deltaPoints[ind],framesMultiplier));

    inTangentsArray = inTangentsArray.map( (el, ind) => el + mul(deltaInTangents[ind],framesMultiplier));

    outTangentsArray = outTangentsArray.map( (el, ind) => el + mul(deltaOutTangents[ind],framesMultiplier));

    pathClosedState = thisProperty.isClosed();

    createPath( points = pointsArray , inTangents = inTangentsArray , outTangents = outTangentsArray , isClosed = pathClosedState);

    } else {

    value;

    }

  • Frank Mansfield

    March 7, 2022 at 12:13 pm

    holey moley… 🙂

    This is way above my pay-grade. I’ll be back in about 2 weeks after I’ve unpicked some of this madness!

    Thanks, Filip, that’s brilliant, cheers
    -f

We use anonymous cookies to give you the best experience we can.
Our Privacy policy | GDPR Policy