ADOBE AFTER EFFECTS: Forum Expressions Tutorials Creative Cloud

correct scaling for in/out tangents in a mask-related script

COW Forums : Adobe After Effects Expressions

<< PREVIOUS   •   FAQ   •   VIEW ALL   •   PRINT   •   NEXT >>
Xavier Gomez
correct scaling for in/out tangents in a mask-related script
on Oct 29, 2011 at 3:41:12 pm

Hello,
i'm writing my first script, which is intended to draw various types of spiral-shaped pathes on a mask.
It's working fine, until i try to implement custom tangents: the direction is ok but the length is really puzzling me and i don't know how to normalize them.


Let's say the ideal (continuous) path has coordinates (X(u), Y(u)), the parameter u running from 0 to infinity. The script takes a finite number of points in that curve and set them as vertices of the path.
Setting only the vertices gives a linear-by-part path, and to mimic the ideal curve one has to implement the tangents.
The in- and out- tangents at point (X(u),Y(u)) are both proportionnal to (X'(u),Y'(u)) (the derivative of the position) but i can't figure out what is the scale to use. I have tested lots of things and apparently it depends on how far are the next and previous vertices in the path.

Someone knows how it works ?


Return to posts index

Dan Ebberts
Re: correct scaling for in/out tangents in a mask-related script
on Oct 29, 2011 at 6:21:12 pm

I haven't worked out the math for a spiral, but if you look at the way that Illustrator creates them, it appears to put all the vertices on two lines that are at right angles to each other. Adjacent tangents also seem to be at right angles to each other with the handles at some fixed percentage (looks like about 57%) of the distance from the vertex to the corner of the right angle. It seems like you should be able to work it out from there.

Dan



Return to posts index

Xavier Gomez
Re: correct scaling for in/out tangents in a mask-related script
on Oct 29, 2011 at 7:07:27 pm

Thank you for the answer, but it doesnt solve my problem.
The script, as i plan it, should be able to handle an arbitray number of vertices per cycle, or even have them in random distribution (so when rotobezier is off it looks like a regular or irregular spider net.), and also be able to play with tangents orientation and length.
But for I this should know what are the smoothest values for the tangents (the ones that reproduce the most the original curve). I tried to have them autocalculated by AE like this:

myMask.rotoBezier = true;
myPath.vertices = V_Array; //the array of vertices
myPath.rotoBezier = true;
myMaskPath.setValue(myPath);

it returns no error but doesnt work, the mask is a concatenation of segments... I'd love to know the correct syntax !


Return to posts index


Dan Ebberts
Re: correct scaling for in/out tangents in a mask-related script
on Oct 30, 2011 at 12:36:12 am

I think it won't work unless you give it some tangents. This seems to work:


{
var V_Array = [[100,100],[200,50],[300,150],[175,210],[150,120],[220,125]];
var IT_Array = [[1,0],[1,0],[1,0],[1,0],[1,0],[1,0]];
var OT_Array = [[-1,0],[-1,0],[-1,0],[-1,0],[-1,0],[-1,0]];

var myLayer = app.project.activeItem.layer(1);
var myMask = myLayer.Masks.addProperty("ADBE Mask Atom");
myProperty = myMask.property("ADBE Mask Shape");
myPath = myProperty.value;
myPath.vertices = V_Array;
myPath.inTangents = IT_Array;
myPath.outTangents = OT_Array;
myPath.closed = false;
myProperty.setValue(myPath);
myMask.rotoBezier = true;
}



Dan



Return to posts index

Xavier Gomez
Re: correct scaling for in/out tangents in a mask-related script
on Nov 2, 2011 at 12:47:33 pm

Thank you, this indeed turns rotobezier ON.
However rotobezier gives poor result unless one inputs some already good enough values for the tangents.

In case someone faces the same problem in the future, I post below a short script based on some doc on Bezier interpolation found there: http://people.sc.fsu.edu/~jburkardt/html/bezier_interpolation.html. (sorry, can't figure out how the link tool is working !)

This script assumes that what AE calls Bezier interpolation is really a Bezier interpolation (there are many other types of interpolations similar to B├ęzier). But it works very well so it should be the case, and the algorythm will vectorize properly most curves (smooth enough, curves with sharp variation like sin with very high frenquency require more vertices).
It creates 3 times more points than the number of vertices of the path (2/3 of these points are here to make sure that the path will walk through them). The funny numbers have their explanation in the doc linked above.

Note: this is just the bit of code needed to get the Vertex and Tangents arrays. The script won't run as it is. To run it, one has to complete the input and add lines like:
var myLayer = app.project.activeItem.layer(1);
var myMask = myLayer.Masks.addProperty("ADBE Mask Atom");
myProperty = myMask.property("ADBE Mask Shape");
myPath = myProperty.value;
myPath.vertices = V_Array; myPath.inTangents = IT_Array; myPath.outTangents = OT_Array;
myPath.closed = CloseBoolean;
myProperty.setValue(myPath);
myMask.rotoBezier = rotoBezierBoolean;
(etc.)

function CurvePoint(u) { // the curve function
var x; var y;
x = ; // input function there
y = ; // input function there
return([x,y]);
}
function VectorNorm(X){ // optionnal, for more smoothing
return(Math.sqrt(X[0]*X[0]+X[1]*X[1]))
}
function Average(X,weightX,Y,weightY){ // optionnal, for more smoothing
var pX=weightX /(weightX+weightY);
var pY=weightY /(weightX+weightY);
return ( pX * X + pY * Y );
}

var Nvertex =....; // the number of vertex you want in your path
var u_min = ... ; // the min value for the curve parameter
var u_max = ... ; // the max value for the curve parameter

// some other parameters for the curve

var CloseBoolean = false; // true for a closed path, false for open
var SmoothBoolean = false;
var rotoBezierBoolean = false;
//
var P_Array=new Array();
var V_Array=new Array(); // the array of vertices
var iT_Array=new Array(); // the array of inTangents
var oT_Array=new Array(); // the array of outTangents
var newP=new Array();

for (i=0; i <= 3*Nvertex; i++) { // creates the array of ALL POINTS (the actual vertices + intermediary hidden control points)
u = u_min + i * (u_max-u_min)/(3*(Nvertex)); // for uniform parameter set. This should be adapted to the need.
P_Array[i] = CurvePoint(u);
}

for (i=0; i < Nvertex ; i++) { // builds the Vertex, inTangents and OutTangents arrays

// builds the Vertex Array
V_Array[i] = P_Array[3*i];

// builds the IN Tangents Array
if (i < 0) iT_Array[i] = ( 2*P_Array[3*i-3] - 9* P_Array[3*i-2] + 18*P_Array[3*i-1] - 11*P_Array[3*i] ) /6;
else{
if (CloseBoolean == false) iT_Array[0] = [0,0];
else iT_Array[0] = (2*P_Array[3*(Nvertex)-3] - 9* P_Array[3*(Nvertex)-2] + 18*P_Array[3*(Nvertex)-1] - 11*P_Array[0])/6;
}
// builds the OUT Tangents Array
if (i < Nvertex-1) oT_Array[i] = (-11* P_Array[3*i] + 18*P_Array[3*i+1] - 9*P_Array[3*i+2] + 2*P_Array[3*i+3])/6;
else{
if (CloseBoolean == false) oT_Array[Nvertex-1]=[0,0];
else oT_Array[Nvertex-1] = ( -11* P_Array[3*(Nvertex-1)] + 18*P_Array[3*(Nvertex-1)+1] - 9*P_Array[3*(Nvertex-1)+2] + 2*P_Array[0] ) /6;
}
}

//some optionnal smoothing
if (SmoothBoolean == true){
Temp= new Array();
var o_norm;
var i_norm;
for (i=0; i &lt; Nvertex ; i++) {
o_norm=VectorNorm(oT_Array[i]);
i_norm=VectorNorm(iT_Array[i]);
if (o_norm+i_norm > 0){
Temp= Average(oT_Array[i],o_norm,-iT_Array[i],i_norm)
oT_Array[i]=(1+(o_norm-i_norm)/(o_norm+i_norm)) * Temp;
iT_Array[i]= -(1-(o_norm-i_norm)/(o_norm+i_norm)) * Temp;
}
}
}


Return to posts index

nadav rock
Re: correct scaling for in/out tangents in a mask-related script
on Oct 24, 2017 at 10:44:14 pm

hi i tried placing values in you script but couldnt get it to work. can you give me an example start to finish how would it look completed for me to just change the mask points i want it to apply to?


Return to posts index

<< PREVIOUS   •   VIEW ALL   •   PRINT   •   NEXT >>
© 2017 CreativeCOW.net All Rights Reserved
[TOP]