Trigonometry: 3D rotation around center point - math

Yeah, yeah, I checked out the suggested questions/answers that were given to me but most involved quaternions, or had symbols in them that I don't even HAVE on my keyboard.
I failed at high school trig, and while I understand the basic concepts of sin and cos in 2D space, I'm at a loss when throwing in a third plane to deal with.
Basically, I have these things: centerpoint, distance, and angles for each of the three axes. Given that information, I want to calculate the point that is -distance- away from the center point, at the specified angles.
I'm not sure I'm explaining this correctly. My intent is to get what amounts to electrons orbiting around a nucleus, if anyone happens to know how to do that. I am working with Java, JRE 6, if there are any utility classes in there that can help.
I don't want just an answer, but also the how and why of the answer. If I'm going to learn something, i want to learn ABOUT it as well. I am not afraid to take a lesson in trigonometry, or how quaternions work, etc. I'm not looking for an entire course on the answer, but at least some basic understanding would be cool.

If you did this in 2D, you would have a point on a plane with certain x and y coordinates. The distance from the origin would be sqrt(x^2+y^2), and the angle atan(y/2).
If you were given angle phi and distance r you would compute x= r*cos(phi); y=r*sin(phi);
To do this in three dimensions you need two angles - angle in XY plane and angle relative to Z axis. Calling these phi and theta, you compute coordinates as
X = r*cos(phi)*sin(theta);
Y = r*sin(phi)*sin(theta);
Z = r*cos(theta);
When I have a chance I will make a sketch to show how that works.

Related

Understanding Angular velocities and their application

I recently had to convert euler rotation rates to vectorial angular velocity.
From what I understand, in a local referential, we can express the vectorial angular velocity by:
R = [rollRate, pitchRate, yawRate] (which is the correct order relative to the referential I want to use).
I also know that we can convert angular velocities to rotations (quaternion) for a given time-step via:
alpha = |R| * ts
nR = R / |R| * sin(alpha) <-- normalize and multiply each element by sin(alpha)
Q = [nRx i, nRy j, nRz k, cos(alpha)]
When I test this for each axis individually, I find results that I totally expect (i.e. 90°pitch/time-unit for 1 time unit => 90° pitch angle).
When I use two axes for my rotation rates however, I don't fully understand the results:
For example, if I use rollRate = 0, pitchRate = 90, yawRate = 90, apply the rotation for a given time-step and convert the resulting quaternion back to euler, I obtain the following results:
(ts = 0.1) Roll: 0.712676, Pitch: 8.96267, Yaw: 9.07438
(ts = 0.5) Roll: 21.058, Pitch: 39.3148, Yaw: 54.9771
(ts = 1.0) Roll: 76.2033, Pitch: 34.2386, Yaw: 137.111
I Understand that a "smooth" continuous rotation might change the roll component mid way.
What I don't understand however is after a full unit of time with a 90°/time-unit pitchRate combined with a 90°/time-unit yawRate I end up with these pitch and yaw angles and why I still have roll (I would have expected them to end up at [0°, 90°, 90°].
I am pretty confident on both my axis + angle to quaternion and on my quaternion to euler formulas as I've tested these extensively (both via unit-testing and via field testing), I'm not sure however about the euler rotation rate to angular-velocity "conversion".
My first bet would be that I do not understand how euler rotation-rates axes interacts on themselves, my second would be that this "conversion" between euler rotation-rates and angular velocity vector is incorrect.
Euler angles are not good way of representing arbitrary angular movement. Its just a simplification used for graphics,games and robotics. They got some pretty hard restrictions like your rotations consist of only N perpendicular axises in ND space. That is not how rotation works in real world. On top of this spherical representation of reper endpoint it creates a lot of singularities (you know when you cross poles ...).
The rotation movement is analogy for translation:
position speed acceleration
pos = Integral(vel) = Integral(Integral(acc))
ang = Integral(omg) = Integral(Integral(eps))
That in some update timer can be rewritten to this:
vel+=acc*dt; pos+=vel*dt;
omg+=eps*dt; ang+=omg*dt;
where dt is elapsed time (Timer interval).
The problem with rotation is that you can not superimpose it like translation. As each rotation has its own axis (and it does not need to be axis aligned, nor centered) and each rotation affect the axis orientation of all others too so the order of them matters a lot. On top of all this there is also gyroscopic moment creating 3th rotation from any two that has not parallel axis. Put all of this together and suddenly you see Euler angles does not match the real geometrics/physics of rotation. They can describe orientation and fake its rotation up to a degree but do not expect to make real sense once used for physic simulation.
The real simulation would require list of rotations described by the axis (not just direction but also origin), angular speed (and its change) and in each simulation step the recomputing of the axis as it will change (unless only single rotation is present).
This can be done by using coumulative homogenous transform matrices along with incremental rotations.
Sadly the majority of programmers prefers Euler angles and Quaternions simply by not knowing that there are better and simpler options and once they do they stick to Euler angles anyway as matrix math seem to be more complicated to them... That is why most nowadays games have gimbal locks, major rotation errors and glitches, unrealistic physics.
Do not get me wrong they still have their use (liek for example restrict free look for camera etc ... but they missused for stuff they are the worse option to use for.

3d rotation around the origin

I know there are plenty of questions about 3d rotation that have been answered here but all of them seem to deal with rotational matrices and quaternions in OpenGL (and I don't really care if I get gimbal lock). I need to get 3d coordinates EX:(x,y,z) of a point that always must be the same distance, I'll call it "d" for now, from the origin. The only information I have as input is the deltax and deltay of the mouse across the screen. So far here is what I have tried:
First:
thetaxz+=(omousex-mouseX)/( width );
thetaxy+=(omousey-mouseY)/( height);
(thetaxy is the angle in radians on the x,y axis and thetaxz on the x,z axis)
(I limit both angles so that if they are less than or equal to 0 they equal 2*PI)
Second:
pointX=cos(thetaxz)*d;
pointY=sin(thetaxy)*d;
(pointX is the point's x coordinate and pointY is the y)
Third:
if(thetaxz)<PI){
pointZ=sqrt(sq(d)-sq(eyeX/d)-sq(eyeY/d));
}else{
pointZ=-sqrt(abs(sq(d)-sq(eyeX/d)-sq(eyeY/d)));
}
(sq() is a function that squares and abs() is an absolute value function)
(pointZ should be the point's z coordinate and it is except at crossing between the positive z hemisphere and negative z hemisphere. As it approaches the edge the point gets stretched further than the distance that it is always supposed to be at in the x and y and seemingly randomly around 0.1-0.2 radians of thetaxz the z coordinate becomes NAN or undefined)
I have thought about this for awhile, and truthfully I'm having difficulty warping my head around the concept of quaternions and rotational matrices however if you can show me how to use them to generate actual coordinates I would be glad to learn. I would still prefer it if I could just use some trigonometry in a few axis. Thank you in advance for any help and if you need more information please just ask.
Hint/last minute idea: I think it may have something to do with the z position affecting the x and y positions back but I am not sure.
EDIT: I drew a diagram:
If you truly want any success in this, you're going to have to bite the bullet and learn about rotation matrices and / or quaternion rotations. There may be other ways to do what you want, but rotation matrices and quaternion rotations are used simply because they are widely understood and among the simplest means of expressing and applying rotations to vectors. Any other representation somebody can come up with will probably be a more complex reformulation of one or both of these. In fact it can be shown rotation is a linear transformation and so can be expressed as a matrix. Quaternion rotations are just a simplified means of rotating vectors in 3D, and therefore have equivalent matrix representations.
That said, it sounds like you're interested in grabbing an object in your scene with a mouse click and rotating in a natural sort of way. If that's the case, you should look at the ArcBall method (there are numerous examples you may want to look over). This still requires you know something of quaternions. You will also find that an at least minimal comprehension of the basic aspects of linear algebra will be helpful.
Update: Based on your diagram and the comments it contains, it looks like all you are really trying to do is to convert Spherical Coordinates to Cartesian Coordinates. As long as we agree on the the notation, that's easy. Let θ be the angle you're calling XY, that is, the angle between the X axis rotated about the Z axis; this is called the azimuth angle and will be in the range [0, 2π) radians or [0°, 360°). Let Φ be an angle between the XY plane and your vector; this is called the elevation angle and will be in the range [-π/2, +π/2] or [-90°, +90°] and it corresponds to the angle you're calling the XZ angle (rotation in the XZ plane about the Y axis). There are other conventions, so make sure you're consistent. Anyway, the conversion is simply:
x = d∙cos(Φ)∙cos(θ)
y = d∙cos(Φ)∙sin(θ)
z = d∙sin(Φ)

Need equations for a parametric parabola + the angle of the tangent at any given time

This may be ridiculously obvious, but math wasn't my strong suit in school. I've been banging my head against the wall long enough that I finally figured I'd ask.
I'm trying to animate a sprite moving along a 2D parabolic path, from point A to point B. Both points are at the same y-coordinate. The desired height of the parabola from the starting/ending y-coordinate is also given (or, if you prefer, a desired velocity). Currently in my code I have a timer firing at a high frequency. I would like to calculate the new location of the ball based on the amount of time that has passed. So a parametric parabola equation should work nicely.
I found this answer from GameDev adequate, until my requirements grew (although I'm not sure its really a parabolic path... I can't follow the derivation of the final equations there provided). Now I would like to squish/stretch the sprite at different points along the parabolic path. But to get the effect to work right, I'll need to rotate the sprite so that it's primary axis is tangential to the path. So I need to be able to derive the angle of the tangent at any given location/time.
I can find all sorts of equations for each of these requirements (parametric parabola, tangent at a point, etc.), but I just can't figure out how to unify them all. Could someone with more math skills help a fellow coder out and provide a set of equations that will work? Thanks ever so much in advance.
What you are missing is this:
Slope = TAN(angle) // in radians
What is the slope? It is how much up/down you move per how much across you move ( dy/dx on some other answers ). For you it is actually (dy/dt)/(dx/dt) since both x and y are functions of time.
So for a trajectory x(t)=Vx*t and y(t)=Vy*t-1/2*g*t^2 the slope is Slope=(Vy-g*t)/Vx where Vx is the initial horizontal velocity, and Vy the initial vertical velocity. g is the gravity (vertical acceleration down). So your rotation in degrees shall be
angle = ATAN( (Vy-g*t)/Vx ) * 180/PI
Basically the slope is equal to the ratio of vertical velocity to horizontal velocity.
Let X be the distance from A to B, Y the desired height of the parabola, V the horizontal speed.
x = Vt
y = Y - (4Y/X^2) (X/2-Vt)^2
tangent dy/dx = (8Y/X^2) (X/2-Vt)

Math programming help for a gimble-based painting machine

I'm an artist involved with building various sorts of computer controlled machines. I've started prototyping a gimble-based XY painting machine and have realized that the maths needed are out of my reach. I'm a decent enough programmer but not strong in math- esp. 3D math.
To get a sense of what I'm needing to do, it might be helpful to look at the rig:
Early prototype:
http://roypardi.com/gimble/gimbleSmall.MOV (small video)
http://roypardi.com/gimble/gimbleLarge.mov (larger video)
The two inner rings represent the X/Y axes and are controlled by stepper motors. I want to be able to use both raster images and vector data (gcode). So I need to be able to address a point in 2D space on the paper/from my data and have the gimble figure out what orientation it needs to be at in order to get there (i.e. how much to step each motor).
I've been searching out 2D > 3D projection, Euler angles, etc. but I'm out of my depth. Any pointers, pushes in the right direction, or code snippets would be most welcome. I can make sense of most programming languages.
Very nice machine you have made, I hope this works for you I believe it is correct.
The way I see it, is to get one angle is simple, but the other is slightly harder to visualise as we have tilted the axis which it turns upon.
I'm going to avoid using tan, as when programming this could result in a division by 0, which could be frustrating. Also Z is going to be the height of the origin above the paper.
YAxis = arcsin( X / sqrt(X² + Z²))
XAxis = arcsin( Y / sqrt(Y² + X² + Z²))
or we could use
XAxis = arcsin(Y / sqrt(Y² + Z²))
YAxis = arcsin( X / sqrt(X² + Y² + Z²))
Also, I'd very much like to see a video of this plotting, if it works.
Edit:
After thinking about it i believe only one solution will work it depends on which axis is affected by the other. Is the YAxis in the Middle or the Xaxis?
I think it's a problem of simple http://en.wikipedia.org/wiki/Trigonometry
Let's say that the distance from the centre of your rings to the nearest point on the paper (which I'll call point 'O' for 'Origin') is distance X.
Take another point P directly north of O, whose distance from O is Y.
To paint this point, you need the angle alpha such that tan(alpha)=Y/X, i.e. you can calculate alpha using the formula "arctan(Y/X)" [arctan is sometimes also known as atan]. Arctan is a trignometric function, which I think you'll probably find defined in the API of a general purpose math library.
The above is the simplest case.
The only other case that I can think of is when the point P isn't due north. Instead of being due north, let's say that its distance is Y1 to the north, and Y2 to the east. The solution is two angles (one angle for each of two rings), one of which is "arctan(Y1/X)" and the other of which is "arctan(Y2/X)".
Perhaps I misunderstand, but I don't believe a gimbal will do what you want. A gimbal can point in any 3D direction, but it cannot move to arbitrary points in 3D space. If the plane of the paper intersects the volume swept by the pen held in the gimbal, the pen might be able to draw a circle, but nothing more. Even drawing a circle is not a sure thing, since in this case the paper would also intersect the volume swept by the gimbal rings; trying to orient the pen would make a ring hit the paper.
I think what you want is a plotter, not a gimbal.

How to map a latitude/longitude to a distorted map?

I have a bunch of latitude/longitude pairs that map to known x/y coordinates on a (geographically distorted) map.
Then I have one more latitude/longitude pair. I want to plot it on the map as best is possible. How do I go about doing this?
At first I decided to create a system of linear equations for the three nearest lat/long points and compute a transformation from these, but this doesn't work well at all. Since that's a linear system, I can't use more nearby points either.
You can't assume North is up: all you have is the existing lat/long->x/y mappings.
EDIT: it's not a Mercator projection, or anything like that. It's arbitrarily distorted for readability (think subway map). I want to use only the nearest 5 to 10 mappings so that distortion on other parts of the map doesn't affect the mapping I'm trying to compute.
Further, the entire map is in a very small geographical area so there's no need to worry about the globe--flat-earth assumptions are good enough.
Are there any more specific details on the kind of distortion? If, for example, your latitudes and longitudes are "distorted" onto your 2D map using a Mercator projection, the conversion math is readily available.
If the map is distorted truly arbitrarily, there are lots of things you could try, but the simplest would probably be to compute a weighted average from your existing point mappings. Your weights could be the squared inverse of the x/y distance from your new point to each of your existing points.
Some pseudocode:
estimate-latitude-longitude (x, y)
numerator-latitude := 0
numerator-longitude := 0
denominator := 0
for each point,
deltaX := x - point.x
deltaY := y - point.y
distSq := deltaX * deltaX + deltaY * deltaY
weight := 1 / distSq
numerator-latitude += weight * point.latitude
numerator-longitude += weight * point.longitude
denominator += weight
return (numerator-latitude / denominator, numerator-longitude / denominator)
This code will give a relatively simple approximation. If you can be more precise about the way the projection distorts the geographical coordinates, you can probably do much better.
Alright. From a theoretical point of view, given that the distortion is "arbitrary", and any solution requires you to model this arbitrary distortion, you obviously can't get an "answer". However, any solution is going to involve imposing (usually implicitly) some model of the distortion that may or may not reflect the reality of the situation.
Since you seem to be most interested in models that presume some sort of local continuity of the distortion mapping, the most obvious choice is the one you've already tried: linear interpolaton between the nearest points. Going beyond that is going to require more sophisticated mathematical and numerical analysis knowledge.
You are incorrect, however, in presuming you cannot expand this to more points. You can by using a least-squared error approach. Find the linear answer that minimizes the error of the other points. This is probably the most straight-forward extension. In other words, take the 5 nearest points and try to come up with a linear approximation that minimizes the error of those points. And use that. I would try this next.
If that doesn't work, then the assumption of linearity over the area of N points is broken. At that point you'll need to upgrade to either a quadratic or cubic model. The math is going to get hectic at that point.
the problem is that the sphere can be distorted a number of ways, and having all those points known on the equator, lets say, wont help you map points further away.
You need better 'close' points, then you can assume these three points are on a plane with the fourth and do the interpolation --knowing that the distance of longitudes is a function, not a constant.
Ummm. Maybe I am missing something about the question here, but if you have long/lat info, you also have the direction of north?
It seems you need to map geodesic coordinates to a projected coordinates system. For example osgb to wgs84.
The maths involved is non-trivial, but the code comes out a only a few lines. If I had more time I'd post more but I need a shower so I will be boring and link to the wikipedia entry which is pretty good.
Note: Post shower edited.

Resources