calculate the angle between two points in after effects - after-effects

I am trying to create an arrow with a line in after effects. The start point is always static, the end point can be moved with sliders and on the end point there is a triangle pointing in the direction the line is pointing.
The line itself is no problem: I used the pen tool to create a path, used create nulls from path and added sliders to the null that controls the end point.
The triangle part is what I can't seem to figure out. On the rotation property of the function:
var p1 = thisComp.layer("Start").transform.position;
var p2 = thisComp.layer("End").transform.position;
radiansToDegrees(Math.atan2(p1,p2);
(Start and End are the Nulls controlling the path)
I assume atan2 is the proper approach in this scenario but Ae gives me an error and the result of the final line is NaN. Any help is much appreciated.

Late answer but try this:
p1 = thisComp.layer("Start").transform.position;
p2 = thisComp.layer("End").transform.position;
v = p2 - p1;
radiansToDegrees(Math.atan2(v[1], v[0]));
In your code there is a close parenthesis missing at the end, that's why the error.

Related

How to create an elbow connector from scratch programatically?

An "elbow connector" in MS-Word is a 3-segment line with a control point in the middle as shown
where if I move the yellow control point sideways, then the length of the two lines on either side change accordingly while the end points remain the same. (Please ignore the "2" in the picture)
I am trying to understand how this works so that I can re-create this. Is there a "line equation" for such a line? I have some points (x,y) that are already in the shape of this elbow connector but I would like to incorporate the functionality of changing the lines on either side by controlling the control point. How would I go about re-creating this?
By dissecting the lines like:
For moving the center(M) only sideways, length of lines 2 and 3 remains the same so the problem becomes how to calculate length (and direction) of the lines 1 and 4.
That can be calculated like:
line1_length = B.x - M.x;
line4_length = M.x - A.x;
For directions a comparison should first be made like:
if(B.x > M.x)...
.
.
.
if(M.x > A.x)...
.
.
.
Beginning points is already known as the position of A and the position of B. By knowing the lengths and directions of lines 1 and 4, the end points can be determined.
Good luck!

Draw line through, instead of between two points in Python

I want to draw a line trough two given points in an image using OpenCV in Python. The definition of a line states as "The shortest distance between two points." But I don't want the line to stop at the points, I want it to go all the way to the borders of my image. Currently I am obviously just using the cv2.line function, with 1 being the thickness of the line.
cv2.line(img,(x1,y1),(x2,y2),blue,1)
The algorithm I'm writing doesn't really matter, I just can't find any function in cv2 or numpy that draws a "line" through two points instead of between them.
Thanks in advance
EDIT: solved it myself
a = (1.0*(y2-y1))/(1.0*(x2-x1))
b = -a*x1+y1
y1_ = (int)(0)
y2_ = (int)(np.shape(img)[1])
x1_ = (int)((y1_-b)/a)
x2_ = (int)((y2_-b)/a)
cv2.line(img,(x1_,y1_),(x2_,y2_),(colors[i][0],colors[i][1],colors[i][2]),5)

Chipmunk Physics: Rotate body smoothly

I haven't been able to find this after scavenging the forums. I would like to implement something like this ... the main character always moves in the direction it's facing. When the player touches the screen, the character will turn to face that touch location, which should cause the body to move in a different direction.
I can get the character to face a touch location as follows:
CGPoint diff = ccpSub(location, self.position);
CGFloat targetAngle = atan2f(diff.y, diff.x);
self.body->a = targetAngle;
I want something along these lines. Get the current angle the character is facing. Turn that angle into a unit vector. Multiply that unit vector by a max_velocity, and apply it to the character. This should should (theoretically) move the character in the direction it is facing at a constant velocity?
This seems to give me what I want:
cpVect rotatedVel = cpvmult(ccpForAngle(self.body->a), MAX_VELOCITY);
self.body->v = cpvlerpconst(self.body->v, rotatedVel, ACCELERATION * dt);
Now all I need is a way to rotate the character's direction slowly over time. How might I do that?
Sounds like you want to do something like this from Chipmunk's Tank demo:
// turn the control body based on the angle relative to the actual body
cpVect mouseDelta = cpvsub(ChipmunkDemoMouse, cpBodyGetPos(tankBody));
cpFloat turn = cpvtoangle(cpvunrotate(cpBodyGetRot(tankBody), mouseDelta));
cpBodySetAngle(tankControlBody, cpBodyGetAngle(tankBody) - turn);
'turn' is calculated relative to the body's current rotation by transforming the direction vector relative to the body's current rotation. The demo smooths out the rotation using constraints (which you might want to consider here too), but you could also just get away with using cpflerpconst() on 'turn' to get a maximum angular velocity too.
What about using the cpBodySetTorque to set object torque to make it spin/rotate?

2d rotation on set of points causes skewing distortion

I'm writing an application in OpenGL (though I don't think this problem is related to that). I have some 2d point set data that I need to rotate. It later gets projected into 3d.
I apply my rotation using this formula:
x' = x cos f - y sin f
y' = y cos f + x sin f
Where 'f' is the angle. When I rotate the point set, the result is skewed. The severity of the effect varies with the angle.
It's hard to describe so I have pictures;
The red things are some simple geometry. The 2d point sets are the vertices for the white polylines you see around them. The first picture shows the undistorted pointsets, and the second picture shows them after rotation. It's not just skew that's occuring with the rotation; sometimes it seems like displacement occurs as well.
The code itself is trivial:
double cosTheta = cos(2.4);
double sinTheta = sin(2.4);
CalcSimplePolyCentroid(listHullVx,xlate);
for(size_t j=0; j < listHullVx.size(); j++) {
// translate
listHullVx[j] = listHullVx[j] - xlate;
// rotate
double xPrev = listHullVx[j].x;
double yPrev = listHullVx[j].y;
listHullVx[j].x = ((xPrev*cosTheta) - (yPrev*sinTheta));
listHullVx[j].y = ((yPrev*cosTheta) + (xPrev*sinTheta));
// translate
listHullVx[j] = listHullVx[j] + xlate;
}
If I comment out the code under '//rotate' above, the output of the application is the first image. And adding it back in gives the second image. There's literally nothing else that's going on (afaik).
The data types being used are all doubles so I don't think its a precision issue. Does anyone have any idea why rotation would cause skewing like the above pictures show?
EDIT
filipe's comment below was correct. This probably has nothing to do with the rotation and I hadn't provided enough information for the problem;
The geometry I've shown in the pictures represents buildings. They're generated from lon/lat map coordinates. In the point data I use to do the transform, I forgot to use an actual projection to cartesian coordinate space and just mapped x->lon, y->lat, and I think this is the reason I'm seeing the distortion. I'm going to request that this question be deleted since I don't think it'll be useful to anyone else.
Update:
As a result of your comments it tunred out the it is unlikely that the bug is in the presented code.
One final other hint: std transform formulars are only valid if the cooridnate system is cartesian,
on ios you sometimes have inverted y Achsis.

Trigonometry across multiple planes

Please bear with me - I'm finding this very difficult to explain.
This is more of a trigonometry question but for what it matters, this is in JavaScript/KineticJS.
I have a series of 'group's which contain 'line's and 'handle's. The way this has to work, it works best for every group to have its own coordinate plane. The problem I'm asking for help on is the only instance where this solution is not ideal.
As these groups rotate, their coordinate plane also rotates. This allows the group object to be reused and its children can measure from the group's origin without any concern about the parent group's orientation. Up is always up... it doesn't matter which way my group is facing.
I'm a new poster, so I cant add an image. However, I think seeing it is vital. Please see http://i.imgur.com/WUVXE.png
The goal is to attach the unattached point of the red arc ('handle') to the black dot on the blue line ('line'). I've set it to always draw 90 degrees just for demonstration purposes.
Despite convention, the API I'm using rotates clockwise, giving the red line an angle of 0, the yellow line an angle of 116, green 180, and blue 296 - all relative to the same origin in the top left of the screen. These angles change, so I'm looking for the formula to calculate the new end point of the red handle.
The X-axis always travels straight down the middle of each line. The line is 20px wide, so there are 10px above or below it the line that are "dead space". The two correct points on the red handle are thus (10,10) and (30,10). Handles have a radius of 20px.
It is not possible to say red.arcEndX = blue.blackDotX, red.arcEndY = blue.blackDotY since the planes for the red and blue group are different. For instance, red's (0,0) is always equal to blue's (200,0). Think of each line as a chain that cannot be detached.
So, how do I calculate the red arc's remaining point? It should attach seamlessly to the edge of the blue line, exactly where the center point of the black dot on the blue line is except translated in to red's coordinate plane.
All of the measurements I may need are available, or can be calculated.
Handle.prototype.update = function() {
/* if we are the red group, this.parent is our group and
'prev' is the blue group. */
var prev = this.parent.getPrev();
// somehow get the new (x,y) for point2 below:
/* KineticJS SVG string. this.origin and this.point1 never
change. This (M)oves to 10,10, draws a (L)ine from
this.origin.x, this.origin.y to this.point1.x, this.point1.y
and (C)urves to this.point2.x, this.point2.y. this.centerXY
is the control point of that curve. */
this.data = "M" + this.origin + "L" + this.point1 + "C" + this.point1 + "," + this.centerXY + "," + this.point2 + "L" + this.origin + "z";
this.shape.setData(this.data);
}
In case anybody stumbles upon this - what I have is correct except I failed to accomodate the origin translation. If you move everything to (0,0) for each plane, do your sin/cos then you'll be OK