Creative Communities of the World Forums

The peer to peer support community for media production professionals.

Activity Forums Adobe After Effects Expressions Multiple corner radii for rounded corners

  • Multiple corner radii for rounded corners

    Posted by Filip Vandueren on May 16, 2023 at 9:18 am

    Hi guys,

    don’t know if there was already a solution for doing this in After Effects like in Illustrator, but here is a method for adding multiple different values for corner radius within 1 shape.

    I reverse engineered the round corners algorithm, so this was a logical next step.

    https://imgur.com/a/QA5oblT

    This only works on Custom Paths, not on built-in rectangles/polygons/…

    It uses an expression, so the “round corners” modifier shouldn’t be added.

    I hope someone will find this useful in the future. And perhaps someone can add/remix the code

    function multiRound(aPath, roundings) {
    // multiple corner-radii
    // Filip Vandueren 2023
    const pts = aPath.points();
    const it = aPath.inTangents(); const ot = aPath.outTangents(); const cl = aPath.isClosed();
    let newPts = []; let newIt = []; let newOt = [];
    for (let i=0; i<pts.length; i++) {
    rounding = roundings[i%roundings.length];
    if ((!cl && (i==0 || i==pts.length-1)) || length(it[i])!=0 || length(ot[i])!=0) {
    // re-use the first and last vertex unaltered if the path is not closed
    // OR if this vertex originally had tangents, it's also not discarded and chamfered, but kept:
    newPts.push(pts[i]);
    newIt.push(it[i]);
    newOt.push(ot[i]);
    } else {
    // add chamfer vertices, discarding the original vertex
    // giving these new vertices tangents creates the rounded corners
    // look at previous vertex
    let j = i-1;
    if (j<0) j+=pts.length; // loop around in closed paths
    let segment = (pts[j]+ot[j]-pts[i]); // consider a linesegment from this vertex to the prev outTangent
    // where should we place the chamferpoint:
    // on that segment, at a point that's 'roundingvalue' away from the current vertex
    // but on a straight linesegment it should never be further than 1/2 the distance
    // (the rounding is limited by the edges length)
    let n = normalize(segment)*Math.min(rounding, length(segment)/(length(ot[j])==0 ? 2 : 1));
    let chamferPoint = pts[i] + n;
    // add the point and it's tangent, using the magic number 0.55
    // it's on the same linesegment
    newPts.push(chamferPoint);
    newIt.push([0,0]);
    newOt.push(-n*0.55);
    // look at next vertex
    j = (i+1)%pts.length; // loop around in closed paths
    segment = (pts[j]+it[j]-pts[i]);
    // same logic as above
    n = normalize(segment)*Math.min(rounding, length(segment)/(length(it[j])==0 ? 2 : 1));
    chamferPoint = pts[i] + n;
    newPts.push(chamferPoint);
    newIt.push(-n*0.55);
    newOt.push([0,0]);
    }
    }
    return createPath(newPts, newIt, newOt, cl);
    }
    multiRound(thisProperty, [20,100,250]);

    Multiple corner radii in after effects

    Filip Vandueren replied 3 weeks, 2 days ago 1 Member · 1 Reply
  • 1 Reply
  • Filip Vandueren

    May 16, 2023 at 9:26 am

    Already had an idea for a remix: negative values give a chamfer instead of rounding:

    https://imgur.com/a/nO51Q10

    function multiRound(aPath, roundings) {
    // multiple corner-radii
    // a negative value will add a chamfer
    // Filip Vandueren 2023
    const pts = aPath.points();
    const it = aPath.inTangents(); const ot = aPath.outTangents(); const cl = aPath.isClosed();
    let newPts = []; let newIt = []; let newOt = [];
    for (let i=0; i<pts.length; i++) {
    rounding = roundings[i%roundings.length];
    if ((!cl && (i==0 || i==pts.length-1)) || length(it[i])!=0 || length(ot[i])!=0) {
    // re-use the first and last vertex unaltered if the path is not closed
    // OR if this vertex originally had tangents, it's also not discarded and chamfered, but kept:
    newPts.push(pts[i]);
    newIt.push(it[i]);
    newOt.push(ot[i]);
    } else {
    // add chamfer vertices, discarding the original vertex
    // giving these new vertices tangents creates the rounded corners
    // look at previous vertex
    let j = i-1;
    if (j<0) j+=pts.length; // loop around in closed paths
    let segment = (pts[j]+ot[j]-pts[i]); // consider a linesegment from this vertex to the prev outTangent
    // where should we place the chamferpoint:
    // on that segment, at a point that's 'roundingvalue' away from the current vertex
    // but on a straight linesegment it should never be further than 1/2 the distance
    // (the rounding is limited by the edges length)
    let n = normalize(segment)*Math.min(Math.abs(rounding), length(segment)/(length(ot[j])==0 ? 2 : 1));
    let chamferPoint = pts[i] + n;
    // add the point and it's tangent, using the magic number 0.55
    // it's on the same linesegment
    newPts.push(chamferPoint);
    newIt.push([0,0]);
    newOt.push(-n*(rounding>0 ? 0.55 : 0));
    // look at next vertex
    j = (i+1)%pts.length; // loop around in closed paths
    segment = (pts[j]+it[j]-pts[i]);
    // same logic as above
    n = normalize(segment)*Math.min(Math.abs(rounding), length(segment)/(length(it[j])==0 ? 2 : 1));
    chamferPoint = pts[i] + n;
    newPts.push(chamferPoint);
    newIt.push(-n*(rounding>0 ? 0.55 : 0));
    newOt.push([0,0]);
    }
    }
    return createPath(newPts, newIt, newOt, cl);
    }
    multiRound(thisProperty, [10,200,-50]);

    View post on imgur.com

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