How to compute sum of angles from sine and cossine? - trigonometry

What is the fastest way to know if the a + b > pi, having only sine and cossine of both a and b? I am hoping to not have to use arccos or arcsin.
Edit: forgot to mention that a and b are in range [0, pi).

With the restriction of the angles domain to [0, pi) that's straightforward. You just have to check if sin(a+b) < 0 and if you already know sin and cos of a and b, then:
sin(a + b) = sin(a)*cos(b) + sin(b)*cos(a)
is what you want.

Related

Describe a plane with z = ax + by + c

I have three points in 3-D space. I want to describe the plane defined by these three points with the equation z = ax + by + c. How can I find the values of a, b, and c which do so?
Said another way: I have a plane described by the equation z = ax + by + c. I have two points which I want to remain in the plane, and a third point which does not yet lie in the plane. I want to rotate the plane about the axis described by the first two points, so that the third point is now in the plane, and then find the a, b, and c which describe this new plane using the same formula. I've looked up how to rotate a point in the plane about the axis (and how to find the correct angle of rotation given the new point I want the plane to pass through), but I'm not sure how to work back to ax + by + c from there.
Said yet another way (this is the most convenient way for me to think about it): I have a function f(x,y) = ax + by + c, and I want to change the value of f(x1,y1) by a certain amount without changing f(x2,y2) or f(x3,y3).
Substitute coordinates of points (xi,yi,zi) to plane equations, and solve this system of linear equations for unknown a,b,c. Cramer's rule is suitable for three-unknowns system. If you have some math library with ready-to-use Gauss elimination, LU method or another solving methods, you can use them.
a*x1 + b*y1 + c = z1
a*x2 + b*y2 + c = z2
a*x3 + b*y3 + c = z3

How to get a point on an ellipse's outline given an angle?

So, I have ellipses given - they are defined by their midpoint, an horizontal radius(rh) and an vertical radius(rv). I'm drawing them using sin/cos and the result looks fairly good to me(just making sure this isn't an error source).
Now say I have an angle(or a direction vector) given and I want to have the point on the ellipse's outline with that angle/direction. My intuitive approach was to simply use the direction vector, normalise it and multiply its x-component with rh, its y-component with rv. Now both my written program AND all the calculations I did on a paper give me not the point I want but another one, though it's still on the ellipse's outline. However, this method works just fine if the direction is one of (1,0), (0, 1), (-1, 0), (0, -1), (so it works for 0°, 90°, 180°, 270°).
Although there is a farily big amount of data about ellipses themselves on the internet, I couldn't find any information about my particular problem - and I couldn't come up with any better solution than the above one.
So, any idea how to achieve this?
If I understand what you are asking then I think that what you need is polar form of an ellipse where the angle is measured from the ellipse centre. Using this form of the ellipse, you will be able to evaulate your elliptic radius value for a given choice of theta and then plot your point.
If you take a look at this gif image you will see why using the parametric angle give you the correct result only at theta = 90, 180, 270 and 360 degrees http://en.wikipedia.org/wiki/File:Parametric_ellipse.gif . Use the polar form for an ellipse and you should get the points that you want.
You are correct - the parametric angle is not the same as the angle between the desired point and the X axis. However, their tangents are proportional (with a factor of rh/rv) so you can use this approach:
Get the tangent of the desired angle
Multiply this tangent by rh/rv
Use trigonometric identities to compute the sine and cosine from the tangent
Scale/position the point according to the parameters (midpoint, rh, rv)
In Python:
from math import copysign, cos, sin, sqrt
class Ellipse:
def __init__(self, mx, my, rh, rv):
self.mx = mx
self.my = my
self.rh = rh
self.rv = rv
def pointFromAngle(self, a):
c = cos(a)
s = sin(a)
ta = s / c ## tan(a)
tt = ta * self.rh / self.rv ## tan(t)
d = 1. / sqrt(1. + tt * tt)
x = self.mx + copysign(self.rh * d, c)
y = self.my + copysign(self.rv * tt * d, s)
return x, y

Camera/Viewing Transformation Matrix

I was wondering if someone can show me the steps into developing a 4x4 transformation matrix that can be used as the viewing transformation.
The camera is at (1, 2, 2)^T
The camera is pointed at the direction (0, 1, 0)^T
The up-vector, which will be mapped to the positive y direction on the image, is the direction (0; 0; 1)^T.
I've looked through my notes and do not understand how to solve these types of problems as I know they are quite common in computer graphics.
You can use the formulas here, just filling in the matrices and multiply each matrix one after the other until you've built up your transformation matrix. (The rotation matrices there may be wrong so double check the formulas here.)
What type of problems are you trying to solve? You didn't really ask a narrow question.
The camera position would be set with a Translation matrix:
[1 0 0 X]
[0 1 0 Y]
[0 0 1 Z]
[0 0 0 1]
substituting [1,2,2]^T for [X,Y,Z]^T
would give you a Translation matrix:
[1 0 0 1]
[0 1 0 2]
[0 0 1 2]
[0 0 0 1]
This can be multiplied by an input vector
[x y z 1]^T
to transform that point, like so:
[1 0 0 1] [x] = x+1
[0 1 0 2] [y] = y+2
[0 0 1 2] [z] = z+2
[0 0 0 1] [1] = 1
For input vector [4,5,6,1] this would yield [5,7,8,1].
See, it just moves or translates the input x,y,z point by the X,Y,Z we plugged in above (ignoring the last component for now).
Remember that a matrix M multiplied by a vector v gives you a vector, call it p
p = M v
think of this as calling a function, sort of like p = sin(x) but instead p = M(v) where M is a transformation function, it happens to be in the form of matrix since the transformations we care about can be represented strictly by linear operators, a fancy way of saying a matrix multiplication, which is just a fancy way of saying the sum of 4 scalar multiplications. To chain these matrix transformations as if they were function calls, just multiply them one after another. (Note that this is a simplification since we need to do division to do perspective transformations, so that's why we cheat and do tricks with a 4x4 matrix instead of a just 3x3 -- that's what the weird term "homogeneneous coordinates" means.)
Does your class have a textbook or lecture notes (if it's online can you link to it)? I would imagine the materials would cover the other transformations and possibly provide examples. You can try it, multiply some vector v = [-9 -8 -7] by the 4x4 matrix above and see what [x y z w] vector you get out of it. Then try plugging in other values for the rotation matrices.
You may run in to tricky bits where you need to multiply the rotation matrix by the translation matrix in the right order: R T would be a different matrix than T R if the translation matrix is any other than 0,0,0.

Inverse Kinematics: Calculating the Jacobian

I am trying to do inverse kinematics for a serial chain of arbitrarily many links.
In the following paper, I have found an example for how to calculate the Jacobian matrix.
Entry (i, j) = v[j] * (s[i] - p[j])
where:
v[j] is the unit vector of the axis of
rotation for joint j
s[i] is the position (int world
coords?) of joint i
p[j] is the position (in world
coords?) of joint j
The paper says that this works if j is a rotational joint with a single degree of freedom. But my rotational joints have no constraints on their rotation. What formula do I then want? (Or am I possibly misunderstanding the term "degree of freedom"?)
This question is old, but I'll answer anyway, as it is something I have thought about but never really gotten around to implement.
Rotational joints with no constraints are called ball joints or spherical joints; they have 3 degrees of freedom. You can use the formula in the tutorial for spherical joints also, if you parameterize each spherical joint in terms of 3 rotational (revolute) joints of one degree of freedom each.
For example: Let N be the number of spherical joints. Suppose each joint has a local transformation T_local[i] and a world transformation
T_world[i] = T_local[0] * ... * T_local[i]
Let R_world[i][k], k = 0, 1, 2, be the k-th column of the rotation matrix of T_world[i]. Define the 3 * N joint axes as
v[3 * j + 0] = R_world[i][0]
v[3 * j + 1] = R_world[i][1]
v[3 * j + 2] = R_world[i][2]
Compute the Jacobian J for some end-effector s[i], using the formula of the tutorial. All coordinates are in the world frame.
Using for example the pseudo-inverse method gives a displacement dq that moves the end-effector in a given direction dx.
The length of dq is 3 * N. Define
R_dq[j] =
R_x[dq[3 * j + 0]] *
R_y[dq[3 * j + 1]] *
R_z[dq[3 * j + 2]]
for j = 0, 1, ..., N-1, where R_x, R_y, R_z are the transformation matrices for rotation about the x-, y-, and z-axes.
Update the local transformations:
T_local[j] := T_local[j] * R_dq[j]
and repeat from the top to move the end-effector in other directions dx.
Let me suggest a simpler approach to Jacobians in the context of arbitrary many DOFs: Basically, the Jacobian tells you, how far each joint moves, if you move the end effector frame in some arbitrarily chosen direction. Let f(θ) be the forward kinematics, where θ=[θ1,...,θn] are the joints. Then you can obtain the Jacobian by differentiating the forward kinematics with respect to the joint variables:
Jij = dfi/dθj
is your manipulator's Jacobian. Inverting it would give you the inverse kinematics with respect to velocities. It can still be useful though, if you want to know how far each joint has to move if you want to move your end effector by some small amount Δx in any direction (because on position level, this would effectively be a linearization):
Δθ=J-1Δx
Hope that this helps.

Projective transformation

Given two image buffers (assume it's an array of ints of size width * height, with each element a color value), how can I map an area defined by a quadrilateral from one image buffer into the other (always square) image buffer? I'm led to understand this is called "projective transformation".
I'm also looking for a general (not language- or library-specific) way of doing this, such that it could be reasonably applied in any language without relying on "magic function X that does all the work for me".
An example: I've written a short program in Java using the Processing library (processing.org) that captures video from a camera. During an initial "calibrating" step, the captured video is output directly into a window. The user then clicks on four points to define an area of the video that will be transformed, then mapped into the square window during subsequent operation of the program. If the user were to click on the four points defining the corners of a door visible at an angle in the camera's output, then this transformation would cause the subsequent video to map the transformed image of the door to the entire area of the window, albeit somewhat distorted.
Using linear algebra is much easier than all that geometry! Plus you won't need to use sine, cosine, etc, so you can store each number as a rational fraction and get the exact numerical result if you need it.
What you want is a mapping from your old (x,y) co-ordinates to your new (x',y') co-ordinates. You can do it with matrices. You need to find the 2-by-4 projection matrix P such that P times the old coordinates equals the new co-ordinates. We'll assume that you're mapping lines to lines (not, for instance, straight lines to parabolas). Because you have a projection (parallel lines don't stay parallel) and translation (sliding), you need a factor of (xy) and (1), too. Drawn as matrices:
[x ]
[a b c d]*[y ] = [x']
[e f g h] [x*y] [y']
[1 ]
You need to know a through h so solve these equations:
a*x_0 + b*y_0 + c*x_0*y_0 + d = i_0
a*x_1 + b*y_1 + c*x_1*y_1 + d = i_1
a*x_2 + b*y_2 + c*x_2*y_2 + d = i_2
a*x_3 + b*y_3 + c*x_3*y_3 + d = i_3
e*x_0 + f*y_0 + g*x_0*y_0 + h = j_0
e*x_1 + f*y_1 + g*x_1*y_1 + h = j_1
e*x_2 + f*y_2 + g*x_2*y_2 + h = j_2
e*x_3 + f*y_3 + g*x_3*y_3 + h = j_3
Again, you can use linear algebra:
[x_0 y_0 x_0*y_0 1] [a e] [i_0 j_0]
[x_1 y_1 x_1*y_1 1] * [b f] = [i_1 j_1]
[x_2 y_2 x_2*y_2 1] [c g] [i_2 j_2]
[x_3 y_3 x_3*y_3 1] [d h] [i_3 j_3]
Plug in your corners for x_n,y_n,i_n,j_n. (Corners work best because they are far apart to decrease the error if you're picking the points from, say, user-clicks.) Take the inverse of the 4x4 matrix and multiply it by the right side of the equation. The transpose of that matrix is P. You should be able to find functions to compute a matrix inverse and multiply online.
Where you'll probably have bugs:
When computing, remember to check for division by zero. That's a sign that your matrix is not invertible. That might happen if you try to map one (x,y) co-ordinate to two different points.
If you write your own matrix math, remember that matrices are usually specified row,column (vertical,horizontal) and screen graphics are x,y (horizontal,vertical). You're bound to get something wrong the first time.
EDIT
The assumption below of the invariance of angle ratios is incorrect. Projective transformations instead preserve cross-ratios and incidence. A solution then is:
Find the point C' at the intersection of the lines defined by the segments AD and CP.
Find the point B' at the intersection of the lines defined by the segments AD and BP.
Determine the cross-ratio of B'DAC', i.e. r = (BA' * DC') / (DA * B'C').
Construct the projected line F'HEG'. The cross-ratio of these points is equal to r, i.e. r = (F'E * HG') / (HE * F'G').
F'F and G'G will intersect at the projected point Q so equating the cross-ratios and knowing the length of the side of the square you can determine the position of Q with some arithmetic gymnastics.
Hmmmm....I'll take a stab at this one. This solution relies on the assumption that ratios of angles are preserved in the transformation. See the image for guidance (sorry for the poor image quality...it's REALLY late). The algorithm only provides the mapping of a point in the quadrilateral to a point in the square. You would still need to implement dealing with multiple quad points being mapped to the same square point.
Let ABCD be a quadrilateral where A is the top-left vertex, B is the top-right vertex, C is the bottom-right vertex and D is the bottom-left vertex. The pair (xA, yA) represent the x and y coordinates of the vertex A. We are mapping points in this quadrilateral to the square EFGH whose side has length equal to m.
Compute the lengths AD, CD, AC, BD and BC:
AD = sqrt((xA-xD)^2 + (yA-yD)^2)
CD = sqrt((xC-xD)^2 + (yC-yD)^2)
AC = sqrt((xA-xC)^2 + (yA-yC)^2)
BD = sqrt((xB-xD)^2 + (yB-yD)^2)
BC = sqrt((xB-xC)^2 + (yB-yC)^2)
Let thetaD be the angle at the vertex D and thetaC be the angle at the vertex C. Compute these angles using the cosine law:
thetaD = arccos((AD^2 + CD^2 - AC^2) / (2*AD*CD))
thetaC = arccos((BC^2 + CD^2 - BD^2) / (2*BC*CD))
We map each point P in the quadrilateral to a point Q in the square. For each point P in the quadrilateral, do the following:
Find the distance DP:
DP = sqrt((xP-xD)^2 + (yP-yD)^2)
Find the distance CP:
CP = sqrt((xP-xC)^2 + (yP-yC)^2)
Find the angle thetaP1 between CD and DP:
thetaP1 = arccos((DP^2 + CD^2 - CP^2) / (2*DP*CD))
Find the angle thetaP2 between CD and CP:
thetaP2 = arccos((CP^2 + CD^2 - DP^2) / (2*CP*CD))
The ratio of thetaP1 to thetaD should be the ratio of thetaQ1 to 90. Therefore, calculate thetaQ1:
thetaQ1 = thetaP1 * 90 / thetaD
Similarly, calculate thetaQ2:
thetaQ2 = thetaP2 * 90 / thetaC
Find the distance HQ:
HQ = m * sin(thetaQ2) / sin(180-thetaQ1-thetaQ2)
Finally, the x and y position of Q relative to the bottom-left corner of EFGH is:
x = HQ * cos(thetaQ1)
y = HQ * sin(thetaQ1)
You would have to keep track of how many colour values get mapped to each point in the square so that you can calculate an average colour for each of those points.
I think what you're after is a planar homography, have a look at these lecture notes:
http://www.cs.utoronto.ca/~strider/vis-notes/tutHomography04.pdf
If you scroll down to the end you'll see an example of just what you're describing. I expect there's a function in the Intel OpenCV library which will do just this.
There is a C++ project on CodeProject that includes source for projective transformations of bitmaps. The maths are on Wikipedia here. Note that so far as i know, a projective transformation will not map any arbitrary quadrilateral onto another, but will do so for triangles, you may also want to look up skewing transforms.
If this transformation has to look good (as opposed to the way a bitmap looks if you resize it in Paint), you can't just create a formula that maps destination pixels to source pixels. Values in the destination buffer have to be based on a complex averaging of nearby source pixels or else the results will be highly pixelated.
So unless you want to get into some complex coding, use someone else's magic function, as smacl and Ian have suggested.
Here's how would do it in principle:
map the origin of A to the origin of B via a traslation vector t.
take unit vectors of A (1,0) and (0,1) and calculate how they would be mapped onto the unit vectors of B.
this gives you a transformation matrix M so that every vector a in A maps to M a + t
invert the matrix and negate the traslation vector so for every vector b in B you have the inverse mapping b -> M-1 (b - t)
once you have this transformation, for each point in the target area in B, find the corresponding in A and copy.
The advantage of this mapping is that you only calculate the points you need, i.e. you loop on the target points, not the source points. It was a widely used technique in the "demo coding" scene a few years back.

Resources