For a project I want to do a very simple Pythagoras calculation in C++. An object is equiped with an IMU sensor that gives either a Quaternion rotation or Euler angles. What I want to know is the opposite sides of the triangle underneath the object.:
I want to know these sides of the triangle for both the X and Y axis (black arrows):
This is pretty much very simple, except for the fact that the object can rotate. When the object is rotated I still want to use the X and Y axis in world space (black arrows), but when yawing the Euler angles of the IMU provide me with pitch and roll, which are in local space (red arrows):
In what way can I still get the world space angles (black arrows) while yawing, to be able to calculate my simple Pythagoras calculation? If I can't get them, is there a way to calculate the opposite sides I want using Quaternions?
We can do the calculation by taking into account the Euler angles in the following order -
Pitch
First of all, as you change the roll of the sensor, the sensor "ray" sweeps out a plane inclined to the horizon at angle pitch. We need to first calculate the closest distance between (i) the line of intersection between the plane and the ground, and (ii) the point directly below the sensor on the ground. This is given by d = h * tan(pitch).
Roll
Next we need to do another trigonometric step. As before the roll sweeps through the plane. The offset distance along the axis perpendicular to the line joining (i) and (ii) is given by f = h / cos(pitch) * tan(roll). This gives the intersection point on the ground to be (d, f)
Yaw
Previously, we considered a frame in which the yaw was zero. We now need to rotate this intersection point around the Z-axis by yaw. Thus the final intersection point is given by (x, y) = (d * cos(yaw) - f * sin(yaw), d * sin(yaw) + f * cos(yaw)). You can calculate the "space angle" you want by taking atan2(y, x).
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.
In my application, I have few screen coordinates through which I draw a Bezier Spline and I need to find the average Velocity and acceleration through that spline.
How should I go about it ?
I will find it in terms of pixel/sec and pixels/square-sec.
and then convert it to m/sec and m/sec sq once the User provides pixel-meter mapping.
But How will I get the velocity or accn as I cant just take start point and end point, It has to be thru that curve.
Ughh, leave the pixel/sex and the pixels/square-sec approach aside for now.
I'm assuming from your question that you have an x-y plot with some sort of Bezier spline, some sort of curve which represents way over time. The x axis usually represents time, while the y axis represents way (length) s.
Velocity is the derivation of length over time, and acceleration the derivation of that. A derivation is simply the ratio of dy/dx in a (preferably) close pair of points.
So, what you need for a start is to interpolate and gather as many points from that Bezier spline. Leaving that up to you. From there,
dy = y(i+1) - yi
dx = x(i+1) - xi
velocity = dy/dx
So a graph of velocity over time would be that plotted on a time basis. Same goes for accelleration, just repeat the process.
You need to differentiate the curve once with respect to the temporal dimension in your plot (here I am assuming the x-axis/horizontal axis represents time; the y-axis/vertical axis represents distance travelled) to gain the local velocity component. Differentiate twice with respect to the same temporal dimension to get the acceleration at a given point. This is basically working out the gradient at each point along the curve for velocity, and the gradient of velocity to get the rate of change of velocity, namely acceleration.
To do this you use numerical integration to get the new quantities (velocity and acceleration) at each discreet point (or coordinate) on your spline based upon the data surrounding that point/coordinate location.
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 !
This may be a little hard to describe since I don't have a sample. I'm trying to find a math function or full 3d function in php or a similar language that can help me with the following effect:
imagine if you were to take a flat sheet or paper and glue it on a glass of water. It wouldn't be flat any more. It would have a curve, and one of its sides might end up being slightly hidden.
Anyone can refer me to a good library or resource on the web where such functions can be found?
Lets say the center of your paper is x=0, and your cylinder is vertical along the y-axis. Your x-coordinate on the paper could be equated to an arc length on the surface of the cylinder. Arc length (s) is equal to the angle (in radians) times the radius. Your radius is given, so you can compute the angle from the arc length and radius. Angle = Arc Length / Radius. Since you now have the angle and the radius, you can compute the new x-offset, which would be (radius * cos(angle)). So your mapping functions would be:
new_x = radius * cos(old_x/radius)
new_y = old_y; //y-coordinate doesn't change
new_z = radius * sin(old_x/radius);
You'll have to enforce boundaries (keep x on the paper, and make sure it's not more than half the circumference (x must be less than or equal to PI*r). Also, watch the signs... especially the z-coordinate, which will depend on whether your coordinate system is right-handed or left-handed, or where you imagine the paper starting on the cylindar (back or front). Finally, you can use standard matrix transforms to move and position the paper/cylinder in 3D space once you have the warped coordinates.