In a 2D plane, I have 2 objects (A and B) with 2 coordinates. Their centers are A(xA, yA) and B(xB, yB) (and C(xC, yC)=C(xB, yA) as AC parallel to the OX line and BC is perpendicular on AC). I can manipulate the rotation of an object and I have access to all usual math operations and can use degrees and radians.
I researched but I couldn't find anything explained in detail.
I also tried using the math formula with arccos formula as follows:
I tried to calculate the distance from A to B (AB) using the Pythagoras theorem, then calculate A to C (AC), then calculate cos(angle)=AC/AB, so the final angle to which I would need to rotate object A towards B is arccos(AC/AB).
Problem is this sounds insanely buggy as you can probably get a lot of digits and ruin everything.
So how can I do this? Please explain mathematically. Thanks!
The simplest way to find the angle between two points is to take their arctangent (a.k.a. inverse tangent). You were on the right track with using cosine, but tangent simplifies the process by not requiring the distance between the points to be known.
As such, you'll want to use an atan2 function in your choice of language. The C# Math.Atan2, for example:
double angle = Math.Atan2(B.Y - A.Y, B.X - A.X);
Note: This particular function returns the angle in radians.
Do you want to rotate object A towards B with C like center of the rotation ?
If it's the case you have only to rotate with an angle of 90 degrees because your triangle is special. But if you want to apply a rotation with a specific angle around a specific center you have to use a transformation TRT.
You will find more explanation here.
Related
I have to use a propriertary graphics-engine for drawing a line. I can rotate the whole drawing by its origin point (P1). What I want, is to rotate it around its center point(M). So basically that it looks like L_correct instead of L_wrong.
I think, it should be possible to correct it, by moving it from P1 to P2. But I cannot figure out what formula could be used, to determine the distance. It must probably involve the angle, width and height...
So basically my question is, if there is a function to determine x2 and y2 based on my available data?
Let's assume you have a primitive method that rotates a drawing by any given angle phi. What you want is to use that primitive to rotate a drawing D around a point M instead. Here is a sketch of how to proceed.
Translate you drawing by -M, i.e., apply the transformation T(P) = P - M to all points P in your drawing. Let T(D) be the translation of D.
Now use the primitive to rotate T(D) by the desired angle phi. Let R(T(D)) be the result.
Now translate the previous result by M and get the rotated drawing. In other words, use the transformation T'(P) = P + M.
Note that in step 1 above M is mapped to the origin 0, where the rotation primitive is known to work. After rotating in step 2, the opposite translation of step 3 puts back the drawing on its original location as this time 0 is mapped to M.
I have a spherical heightfield, defined by a function f(x, y, z) which returns the distance from the origin of the surface of the heightfield of a line which passes from the origin through (x,y,z).
(In other words, the isosurface for my heightfield is |x,y,z| = f(x,y,z).)
(Also, for the sake of discussion below, I'm going to assume that surface(x,y,z) is the location of the point on the surface directly below (x,y,z).)
When rendering this, I need to calculate the normal for any point on the heightfield. What's the cheapest way of doing this?
To calculate the normal of a point on a rectangular heightfield, the usual trick is to offset (x,y,z) slightly in two directions parallel to the nominal surface, calculate three points on the heightfield to form a triangle, and then use the cross product to calculate the triangle's normal. This is easy as the three points can simply be surface(x,y,z), surface(x+1,y,z) and surface(x,y+1,z) (or similar). But for a spherical heightfield it's a little trickier because the normal can point in any direction. Simply displacing by x and y won't do because if two of my points fall on a radius, then surface() of them will return the same location and I won't get a triangle.
In the past what I've done is to use the vector <x,y,z> as a radius from the sphere's origin; then calculate a vector perpendicular to it; then rotate this vector around <x,y,z> to give me my three points. But this is fiddly and expensive and shouldn't be necessary. There must be a cheaper way. What is it?
Calculate the surface() points and, if they are close enough to cause problems, carry out the more expensive (but accurate) calculation; otherwise, use the cheap/easy calculation.
I cant seem to figure out how to calculate the incline of a curve for the following situation...
Essentially what I am trying to do is increase the speed of an object based on the incline of the curve at a particular point. The speed will be reduced if the incline is upwards and increase if downward.
I was using the derivative of a point t on the bezier curve to establish the tangent but this doesnt seem to be right as I would expect that value to be negative if the slope is downward.
I have been using the below equation for the tangent to evaluate X, Y and Z but then I only use Y to establish the incline...I think that step may be wrong
Any ideas?
EDIT:
Ultimately this is an object moving along an inclined plane but I cant establish the angle of the plane in order to do this, I believe if I could correctly find the angle it may solve the problem. I tried to take the point in question and then another point in front (so for example t = 0.5 and then a point in front would be t=0.51) and then calculate the angle using tan. I completely ignore the Z axis but is that wrong? If not how should I calculate the angle?
Thanks a lot
This should help: http://www.physicsclassroom.com/Class/vectors/U3L3e.cfm .
Essentially, you need to calculate the angle of inclination. If the angle is \theta , then the acceleration depends on sin(\theta).
I am assuming z as the vertical dimension.
if dx,dy and dz is are the gradients in each directions, dw = sqrt( dx^2+dy^2). \theta = tan_inverse( dz/dw). Acceleration = g*sin(\theta).
NOTE: You can directly calculate sin(\theta) without explicitly calculating \theta. sin(\theta) = dz/sqrt(dx^2+dy^2+dz^2).
=== More formal description ===
Let x be the east-west dimension, y be the north-south dimension and z be the up-down dimension.
Let z = F(x,y) give the elevation of the terrain at any given location x,y.
Calculate dz/dx = fx(x,y) and dz/dy = fy(x,y), the partial derivatives of z w.r.t to x and y.
Now, sin(\theta) = dz/sqrt(dx^2+dy^2+dz^2) = 1/(sqrt( (dx/dz)^2+ (dy/dz)^2 )= 1/(sqrt( (1/fx(x,y))^2, (1/fy(x,y))^2 ).
This is how you calculate sin(\theta).
The value of derivation is negative when the slope is "downward". And yes, the derivation is the tangent of the slope angle. Only you should pay attention to the directions. They can change the sign, of course. Only you should take dy/dx, not dy/something else. That is all on 2d curves.
You mention Z in the last paragraph. You curve is 3D? Then, of course, the term "derivation" should be put more precisely. Derivation of what to what do you need? The second idea is - please, explain better, what do you want. BTW, maybe after you write down the task correctly, you'll see the solution as obvious.
If it is 3D, let us say, you have your curve as 3 functions of x(t), y(t), z(t). then you need dz/dq, where dq= dt*sqrt((dx/dt)^2+(dy/dt)^2). Obviously, isn't it?
As I said, no maths here. Merely Pythagor's theorem and proportions. (I take z as height)
Addition: it can be rerecounted as tan(a)=dz/(dt*sqrt((dx/dt)^2+(dy/dt)^2)) => tan(a)=(dz/dt)/sqrt((dx/dt)^2+(dy/dt)^2)) ==> a=ATAN((dz/dt)/sqrt((dx/dt)^2+(dy/dt)^2)). But look out for directions you are moving! They can reverse the sign. For under sqrt(^2+^2) we have lost the direction of the dt proection.
If I have 2 sets of points I can rotate one around with Procrustes analysis to align one with the other.
But suppose these 2 sets of points each are attached to images and I would like to rotate the images as well. Is there any way I can also rotate the image, instead of rotating just the points? The tutorial there uses a dot product for rotation (solve u, s, v = svd(p1', p2) and then do p2 . v . u', p' is transposed p)
However that doesn't tell me what the angle between the images is.
The page on wikipedia calculates an angle between each pair of points I think.
Maybe what I'm asking is impossible? If I rotate the first set of points to align it with the first, can't I also rotate the respective images by an angle as well? Point being, which angle is that?
I noticed that v . u' gives me a 2 x 2 matrix which seems to be the rotation matrix (there's a wikipedia page but I can't link there due to posting priviledges). I got the sin and cos of the third and first elements and then used arctan2, but the results I'm getting are kind of weird. I know they have to be transformed from radians but I'm not convinced what I'm doing is right. Trying the rotation it gives me on gimp makes it seem like it's not what I want, but I'll test some more.
It seems like your approach is mostly correct. Two things which come to mind:
1) The paper you linked to (Procrustes analysis) involves a translation and a scaling in addition to rotation. Depending on whether or not those operations are also performed on your images, you may end up with strange results that don't appear to match.
2) I think you may be overcomplicating your angle calculation. v * u' appears to be the correct rotation matrix, but I believe the correct angle only requires one of the matrix entries in the 2x2 matrix. For instance, just use acos() of the first matrix entry. As you've noticed, this will (depending on the program) give you an answer in radians which you'll have to convert to degrees if you want to try out the rotation in gimp, etc.
Hope this helps!
I have a frustum (truncated pyramid) and I need to compute a bounding sphere for this frustum that's as small as possible. I can choose the centre to be right in the centre of the frustum and the radius be the distance to one of the "far" corners, but that usually leaves quite a lot of slack around the narrow end of the frustum
This seems like simple geometry, but I can't seem to figure it out. Any ideas?
This is probably not the answer you're looking for, but you could compute all the verts of the frustum and plug them into a general minimum bounding sphere algorithm, like the miniball implementation.
Well, there's http://www.cgafaq.info/wiki/Minimal_enclosing_sphere of course (via Google).
I'd think there are two possibilities. One (if the frustum is very flat) would be that the opposite points of the base become opposite points on the sphere. The other (if the frustum is very tall) would be that opposite points of the frustum would be on the sphere and you'd figure out the sphere from those four points (one point on the base, one opposite the first on the base, one opposite the first on the higher square, one adjacent the first on the higher square).
Figure out the first sphere. If the frustum fits in it, that's your answer. Otherwise, the second sphere would be your answer.
There are several algorithms and implementations out there for this problem (see also this post).
For 2D and 3D, Gärtner's implementation is probably the fastest.
For higher dimensions (up to 10,000, say), take a look at https://github.com/hbf/miniball, which is the implementation of an algorithm by Gärtner, Kutz, and Fischer (note: I am one of the co-authors).
For very, very high dimensions, core-set (approximation) algorithms will be faster.
In your particular application, you may want to try either of the first two algorithms. Both run in O(n) with a very small constant and are numerically stable.
The way to do this is to find a sphere that fits 4 points on your frustum. If this is a proper frustum (a truncated pyramid - my bad I was assuming a cylindrical fristum), then you get two points from opposite corners of the top quad, and the other two from the bottom quad, out of phase with the top two. Then use this to get your sphere.
Well let's solve with math.
Using right hand Y up coordinate system (forward is –Z axis), for frustum with viewport width w, height h, near plane n, far plane f, X axis field of view angle fov, then the minimal bounding sphere is
k = sqrt(1+(h/w)^2) * tan(fov/2)
if( k^2 >= (f-n)/(f+n) )
{
C = (0, 0, -f)
R = f*k
}
else
{
C = (0, 0, -0.5 * (f+n) * (1+k^2))
R = 0.5 * sqrt( (f-n)^2 + 2*(f^2+n^2)*k^2 + (f+n)^2*k^4 )
}
C is the center of the sphere, in view space, and R is radius.
I put details in my blog if you are interested:
https://lxjk.github.io/2017/04/15/Calculate-Minimal-Bounding-Sphere-of-Frustum.html
Any set of four noncoplanar points defines a sphere. Assuming you're using a four-sided pyramid for your frustum, there are 70 possible sets of four points. Try all 70 spheres and see which is the smallest.
Given that your frustum probably has some symmetries, you can probably pick the four points on opposite corners and use plinth's solution.
You need to find a point on a "vertical" line down the center of the frustum where the distance to an edge on the bottom and top of the frustum (assuming it's symmetrical) is the same.
solve such that a point on the bottom is Xb, Yb, Zb, a point on the top is Xt, Yt, Zt and the line is a point Xp, Yp, Zp plus a vector Ax, By, Cz.
so solve the equation
sqrt( (Xb - (Xp + VAx) )^2 + (Yb - (Yp + VBy))^2 + (Zb - (Zp + VCy))^2) =
sqrt( (Xt - (Xp + VAx) )^2 + (Yt - (Yp + VBy))^2 + (Zt - (Zp + VCy))^2).
The only variable in there is the scalar V.
Strictly speaking (according to this) the base of the frustum can be any polygon and, also strictly speaking, that polygon doesn't even have to be convex. That said, to get a general solution to the problem, I think you might need to use (almost) all the vertices as suggested above. There might be special cases, though, whose solution might (as suggested above) only require the comparison of a couple of spheres. I like the link by Anthony above: Megiddo provides a transformation that he claims yields a solution in O(n) (!) time. Not bad !