Incorrect conversion from quaternions to euler angles and back - math

I am converting angles-axis representation to Euler angles. I decided to check and make sure that the Euler angles I got from the conversion would lead back to the original axis-angle. I print out the values, but they do not match! I have read http://forum.onlineconversion.com/showthread.php?t=5408 and http://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles as well as similar conversion questions on this website.
In the code below I start with angle 'angle' and axis (rx,ry,rz), then I convert it to quaternions (q0,q1,q2,q3). I convert the quaternions to euler angles (roll, pitch, yaw). Then to check it, I convert (roll,pitch,yaw) back to axis-angle as cAngle and (cRx,cRy,cRz). I then do some bounds checking on (roll, pitch,yaw) to keep the numbers between -pi and pi, and then I print them out. It should be that cAngle=angle and (cRx,cRy,cRz)=(rx,ry,rz), but these are both wrong.
The rotations are in order Z*Y*X as is common, I believe. Is there someting wrong with my math? I plan on eventually adding special cases for when pitch is 0 or PI as in http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/ but right now I think the problem is separate.
//input is angle 'angle' and axis '(rx,ry,rz)'
//convert rx,ry,rz, angle, into roll, pitch, yaw
double q0 = Math.Cos(angle / 2);
double q1 = Math.Sin(angle / 2) *Math.Cos(rx);
double q2 = Math.Sin(angle / 2) * Math.Cos(ry);
double q3 = Math.Sin(angle / 2) * Math.Cos(rz);
double roll = Math.Atan2(2 * (q0 * q1 + q2 * q3), 1 - 2 * (q1 * q1 + q2 * q2));
double pitch = Math.Asin(2 * (q0 * q2 - q3 * q1));
double yaw = Math.Atan2(2 * (q0 * q3 + q1 * q2), 1 - 2 * (q2 * q2 + q3 * q3));
//convert back to angle axis
double cAngle = 2 * Math.Cos(Math.Cos(roll / 2) * Math.Cos(pitch / 2) * Math.Cos(yaw / 2) + Math.Sin(roll / 2) * Math.Sin(pitch / 2) * Math.Sin(yaw / 2));
double cRx = Math.Acos((Math.Sin(roll / 2) * Math.Cos(pitch / 2) * Math.Cos(yaw / 2) - Math.Cos(roll / 2) * Math.Sin(pitch / 2) * Math.Sin(yaw / 2)) / Math.Sin(cAngle / 2));
double cRy = Math.Acos((Math.Cos(roll / 2) * Math.Sin(pitch / 2) * Math.Cos(yaw / 2) + Math.Sin(roll / 2) * Math.Cos(pitch / 2) * Math.Sin(yaw / 2)) / Math.Sin(cAngle / 2));
double cRz = Math.Acos((Math.Cos(roll / 2) * Math.Cos(pitch / 2) * Math.Sin(yaw / 2) - Math.Sin(roll / 2) * Math.Sin(pitch / 2) * Math.Cos(yaw / 2)) / Math.Sin(cAngle / 2));
//stay within +/- PI of 0 to keep the number small
if (roll > 3.1416) roll = -Math.PI + (roll - Math.PI);
if (roll < -3.1416) roll = Math.PI + (roll - (-1) * Math.PI);
if (pitch > 3.1416) pitch = -Math.PI + (pitch - Math.PI);
if (pitch < -3.1416) pitch = Math.PI + (pitch - (-1) * 3.1416F);
if (yaw > 3.1416) yaw = -Math.PI + (yaw - Math.PI);
if (yaw < -3.1416) yaw = Math.PI + (yaw - (-1) * Math.PI);
Console.WriteLine("original angle, axis " + angle + ": " + rx + ", " + ry + ", " + rz);
Console.WriteLine("converted angle, axis " + cAngle + ": " + cRx + ", " + cRy + ", " + cRz);
Console.WriteLine("quats " + q0 + ", " + q1 + ", " + q2 + ", " + q3);
Console.WriteLine("roll,pitch,yaw: " + roll + ", " + pitch + ", " + yaw);

I didn't (and I won't) check your code. Even if your code is correct, your test fails for at least 2 reasons.
There are 2 ways to represent the same rotation with Euler angles. See also Euler angle to Quaternion then Quaternion to euler angle, that question is basically about the same problem you are having.
Quaternions have the so-called double covering property: Two unit quaternions correspond to every rotation.
That is, even if your conversions are correct, you can get the other representation and not the one you started with. It doesn't matter whether you started with Euler angles or quaternions.
If you want to test your code, I suggest checking orthogonal rotations of the unit basis vectors. For example rotate [1, 0, 0] with 90 degrees appropriately to get [0, 1, 0]. Check whether you really get the expected [0, 1, 0], etc.
If you got the rotations of all 3 basis vectors right then your code is most likely correct.
This test has the advantage of being unambiguous and if you mess up something (for example a sign in a formula) this test helps you a lot in finding your mistake.
I wouldn't use Euler angles as they screw up the stability of your application. They are not very handy either.

Using quaternions are incorrect.
I want to add to this answer. People use quaternions by convention even when the application is incorrect so this is important.
If your subject of rotation cannot roll then using quaternions to represent your rotation is Incorrect. Quaternions encode 3 dimensions of rotation into the system and if your system has only two the representation is mismatched and incorrect.
Quaternions are an over complicated representation of rotation used to fix gimbal lock and provide better composability ONLY for rotations that involve pitch, yaw AND roll.
If you only have pitch and yaw. Quaternion transformations can give you an answer involving roll which is fundamentally incorrect. Zeroing the roll angle does not prevent your transformations from having a roll value. The Quaternion is not encoded with the concept of rotations Without a roll so it is incorrect to use it here.
For things that can only pitch and yaw and NOT roll, use entities that do not involve the concept of "rolling" like 3D Cartesian coordinates or spherical coordinates (not euler angles). That is enough and more correct. You will not suffer from gimbal lock under these conditions... using quaternions for this is not just over kill but WRONG.

Related

Moving slowly an initial angle until it reach a final angle

I will try to be very descriptive with this. I'm editing a game right now and the scenario is a 3D area.
I have an initial angle, writen as a direction vector, and another vector which haves different coordinates. As we know, the angle between 2 vectors is given by the formula: Theta = ACos( DotProduct( vec1, vec2 ) / ( VectorLength( vec1 ) * VectorLength( vec2 ) ) )
So let's describe the scenario: I'm currently programming some kind of stationary weapon, a sentry gun, this thing moves slowly his "head", shooting bullets to enemies. That angle rotation thing is my problem.
Let's imagine this: I have my sentry gun on a empty 3D area, and a "enemy" spawns over there. I can currently get the direction vector of my sentry's view angle, and the direction vector between my sentry and the player. Let's guess, using the formula described, his separation angle is 45 degrees. My sentry gun thinks (calls a function) at every 0.1 seconds, and I want to move his head 5 degrees at every thinking function until it reach the the player (ie, both vectors are nearly equal), and that means it will reach the player (if player keeps on its position...) in 0.9 seconds (5 degrees from 45)
How I can move sentry's view angle slowly until it reach a target? In 2D is easily but know I'm fighting with a 3D scenario, and I'm currently lost with this.
Any help would be appreciated, and about coding, I will be grateful with a pseudocode. Thanks! (and sorry for my english)
What you need is called SLERP - spherical linear interpolation
Your starting direction vector is p0 there, goal direction is p1, Omega is your Theta, and t parameter varies in range 0..1 with needed step
Delphi example for 2D case (it is easy to control)
var
p0, p1: TPoint;
i, xx, yy: Integer;
omega, InvSinOmega, t, a0, a1: Double;
begin
P0 := Point(0, 200);
P1 := Point(200, 0);
omega := -Pi / 2;
InvSinOmega := 1.0 / Sin(omega);
Canvas.Brush.Color := clRed;
Canvas.Ellipse(120 + P0.X, 120 + P0.Y, 120 + P0.X + 7, 120 + P0.Y + 7);
Canvas.Ellipse(120 + P1.X, 120 + P1.Y, 120 + P1.X + 7, 120 + P1.Y + 7);
for i := 1 to 9 do begin
t := i / 10;
a0 := sin((1 - t) * omega) * InvSinOmega;
a1 := sin(t * omega) * InvSinOmega;
xx := Round(P0.X * a0 + P1.X * a1);
yy := Round(P0.Y * a0 + P1.Y * a1);
Canvas.Brush.Color := RGB(25 * i, 25 * i, 25 * i);
Canvas.Ellipse(120 + xx, 120 + yy, 120 + xx + 9, 120 + yy + 9);
end;

Oculus rift, quaternion and euler, how to increase range

I have access to rotation degrees from oculus. Quanterion to Euler, Euler to degrees.
Range of pitch, roll and yaw is from -90 to 90. Is there any way to increase range -180 to 180? I know that can't use arcus functions, because it has ranges from -pi/2 to pi/2
double a = ts.HeadPose.ThePose.Orientation.x;
double b = ts.HeadPose.ThePose.Orientation.y;
double c = ts.HeadPose.ThePose.Orientation.z;
double d = ts.HeadPose.ThePose.Orientation.w;
double kat_x = atan2(2 * (a*b + c*d), 1 - 2 * (b*b + c*c));
kat_x = (kat_x * 180) / 3.1415;
double kat_y = asin(2 * (a*c - d*b));
kat_y = (kat_y * 180) / 3.1415;
double kat_z = atan2(2 * (a*d + b*c), 1 - 2 * (c*c + d*d));
kat_z = (kat_z * 180) / 3.1415;
Ok now it's working. Instead of using atan i needed to use atan2

How to find the interception coordinates of a moving target in 3D space?

Assuming I have a spaceship (source); And an asteroid (target) is somewhere near it.
I know, in 3D space (XYZ vectors):
My ship's position (sourcePos) and velocity (sourceVel).
The asteroid's position (targetPos) and velocity (targetVel).
(eg. sourcePos = [30, 20, 10]; sourceVel = [30, 20, 10]; targetPos = [600, 400, 200]; targetVel = [300, 200, 100]`)
I also know that:
The ship's velocity is constant.
The asteroid's velocity is constant.
My ship's projectile speed (projSpd) is constant.
My ship's projectile trajectory, after being shot, is linear (/straight).
(eg. projSpd = 2000.00)
How can I calculate the interception coordinates I need to shoot at in order to hit the asteroid?
Notes:
This question is based on this Yahoo - Answers page.
I also searched for similar problems on Google and here on SO, but most of the answers are for 2D-space, and, of the few for 3D, neither the explanation nor the pseudo-codes explain what is doing what and/or why, so I couldn't really understand enough to apply them on my code successfully. Here are some of the pages I visited:
Danik Games Devlog, Blitz3D Forums thread, UnityAnswers, StackOverflow #1, StackOverflow #2
I really can't figure out the maths / execution-flow on the linked pages as they are, unless someone dissects it (further) into what is doing what, and why;
Provides a properly-commented pseudo-code for me to follow;
Or at least points me to links that actually explain how the equations work instead of just throwing even more random numbers and unfollowable equations in my already-confused psyche.
I find the easiest approach to these kind of problems to make sense of them first, and have a basic high school level of maths will help too.
Solving this problem is essentially solving 2 equations with 2 variables which are unknown to you:
The vector you want to find for your projectile (V)
The time of impact (t)
The variables you know are:
The target's position (P0)
The target's vector (V0)
The target's speed (s0)
The projectile's origin (P1)
The projectile's speed (s1)
Okay, so the 1st equation is basic. The impact point is the same for both the target and the projectile. It is equal to the starting point of both objects + a certain length along the line of both their vectors. This length is denoted by their respective speeds, and the time of impact. Here's the equation:
P0 + (t * s0 * V0) = P1 + (t * s0 * V)
Notice that there are two missing variables here - V & t, and so we won't be able to solve this equation right now. On to the 2nd equation.
The 2nd equation is also quite intuitive. The point of impact's distance from the origin of the projectile is equal to the speed of the projectile multiplied by the time passed:
We'll take a mathematical expression of the point of impact from the 1st equation:
P0 + (t * s0 * V0) <-- point of impact
The point of origin is P1
The distance between these two must be equal to the speed of the projectile multiplied by the time passed (distance = speed * time).
The formula for distance is: (x0 - x1)^2 + (y0 - y1)^2 = distance^2, and so the equation will look like this:
((P0.x + s0 * t * V0.x) - P1.x)^2 + ((P0.y + s0 * t * V0.y) - P1.y)^2 = (s1 * t)^2
(You can easily expand this for 3 dimensions)
Notice that here, you have an equation with only ONE unknown variable: t!. We can discover here what t is, then place it in the previous equation and find the vector V.
Let me solve you some pain by opening up this formula for you (if you really want to, you can do this yourself).
a = (V0.x * V0.x) + (V0.y * V0.y) - (s1 * s1)
b = 2 * ((P0.x * V0.x) + (P0.y * V0.y) - (P1.x * V0.x) - (P1.y * V0.y))
c = (P0.x * P0.x) + (P0.y * P0.y) + (P1.x * P1.x) + (P1.y * P1.y) - (2 * P1.x * P0.x) - (2 * P1.y * P0.y)
t1 = (-b + sqrt((b * b) - (4 * a * c))) / (2 * a)
t2 = (-b - sqrt((b * b) - (4 * a * c))) / (2 * a)
Now, notice - we will get 2 values for t here.
One or both may be negative or an invalid number. Obviously, since t denotes time, and time can't be invalid or negative, you'll need to discard these values of t.
It could very well be that both t's are bad (in which case, the projectile cannot hit the target since it's faster and out of range). It could also be that both t's are valid and positive, in which case you'll want to choose the smaller of the two (since it's preferable to hit the target sooner rather than later).
t = smallestWhichIsntNegativeOrNan(t1, t2)
Now that we've found the time of impact, let's find out what the direction the projectile should fly is. Back to our 1st equation:
P0 + (t * s0 * V0) = P1 + (t * s0 * V)
Now, t is no longer a missing variable, so we can solve this quite easily. Just tidy up the equation to isolate V:
V = (P0 - P1 + (t * s0 * V0)) / (t * s1)
V.x = (P0.x - P1.x + (t * s0 * V0.x)) / (t * s1)
V.y = (P0.y - P1.y + (t * s0 * V0.y)) / (t * s1)
And that's it, you're done!
Assign the vector V to the projectile and it will go to where the target will be rather than where it is now.
I really like this problem since it takes math equations we learnt in high school where everyone said "why are learning this?? we'll never use it in our lives!!", and gives them a pretty awesome and practical application.
I hope this helps you, or anyone else who's trying to solve this.
If you want a projectile to hit asteroid, it should be shoot at the point interceptionPos that satisfy the equation:
|interceptionPos - sourcePos| / |interceptionPos - targetPos| = projSpd / targetVel
where |x| is a length of vector x.
In other words, it would take equal amount of time for the target and the projectile to reach this point.
This problem would be solved by means of geometry and trigonometry, so let's draw it.
A will be asteroid position, S - ship, I - interception point.
Here we have:
AI = targetVel * t
SI = projSpd * t
AS = |targetPos - sourcePos|
vector AS and AI direction is defined, so you can easily calculate cosine of the SAI angle by means of simple vector math (take definitions from here and here). Then you should use the Law of cosines with the SAI angle. It will yield a quadratic equation with variable t that is easy to solve (no solutions = your projectile is slower than asteroid). Just pick the positive solution t, your point-to-shoot will be
targetPos + t * targetVel
I hope you can write a code to solve it by yourself. If you cannot get something please ask in comments.
I got a solution. Notice that the ship position, and the asteroid line (position and velocity) define a 3D plane where the intercept point lies. In my notation below | [x,y,z] | denotes the magnitude of the vector or Sqrt(x^2+y^2+z^2).
Notice that if the asteroid travels with targetSpd = |[300,200,100]| = 374.17 then to reach the intercept point (still unknown, called hitPos) will require time equal to t = |hitPos-targetPos|/targetSpd. This is the same time the projectile needs to reach the intercept point, or t = |hitPos - sourcePos|/projSpd. The two equations are used to solve for the time to intercept
t = |targetPos-sourcePos|/(projSpd - targetSpd)
= |[600,400,200]-[30,20,10]|/(2000 - |[300,200,100]|)
= 710.81 / ( 2000-374.17 ) = 0.4372
Now the location of the intetception point is found by
hitPos = targetPos + targetVel * t
= [600,400,200] + [300,200,100] * 0.4372
= [731.18, 487.45, 243.73 ]
Now that I know the hit position, I can calculate the direction of the projectile as
projDir = (hitPos-sourcePos)/|hitPos-sourcePos|
= [701.17, 467.45, 233.73]/874.52 = [0.8018, 0.5345, 0.2673]
Together the projDir and projSpd define the projectile velocity vector.
Credit to Gil Moshayof's answer, as it really was what I worked off of to build this. But they did two dimensions, and I did three, so I'll share my Unity code in case it helps anyone along. A little long winded and redundant. It helps me to read it and know what's going on.
Vector3 CalculateIntercept(Vector3 targetLocation, Vector3 targetVelocity, Vector3 interceptorLocation, float interceptorSpeed)
{
Vector3 A = targetLocation;
float Ax = targetLocation.x;
float Ay = targetLocation.y;
float Az = targetLocation.z;
float As = targetVelocity.magnitude;
Vector3 Av = Vector3.Normalize(targetVelocity);
float Avx = Av.x;
float Avy = Av.y;
float Avz = Av.z;
Vector3 B = interceptorLocation;
float Bx = interceptorLocation.x;
float By = interceptorLocation.y;
float Bz = interceptorLocation.z;
float Bs = interceptorSpeed;
float t = 0;
float a = (
Mathf.Pow(As, 2) * Mathf.Pow(Avx, 2) +
Mathf.Pow(As, 2) * Mathf.Pow(Avy, 2) +
Mathf.Pow(As, 2) * Mathf.Pow(Avz, 2) -
Mathf.Pow(Bs, 2)
);
if (a == 0)
{
Debug.Log("Quadratic formula not applicable");
return targetLocation;
}
float b = (
As * Avx * Ax +
As * Avy * Ay +
As * Avz * Az +
As * Avx * Bx +
As * Avy * By +
As * Avz * Bz
);
float c = (
Mathf.Pow(Ax, 2) +
Mathf.Pow(Ay, 2) +
Mathf.Pow(Az, 2) -
Ax * Bx -
Ay * By -
Az * Bz +
Mathf.Pow(Bx, 2) +
Mathf.Pow(By, 2) +
Mathf.Pow(Bz, 2)
);
float t1 = (-b + Mathf.Pow((Mathf.Pow(b, 2) - (4 * a * c)), (1 / 2))) / (2 * a);
float t2 = (-b - Mathf.Pow((Mathf.Pow(b, 2) - (4 * a * c)), (1 / 2))) / (2 * a);
Debug.Log("t1 = " + t1 + "; t2 = " + t2);
if (t1 <= 0 || t1 == Mathf.Infinity || float.IsNaN(t1))
if (t2 <= 0 || t2 == Mathf.Infinity || float.IsNaN(t2))
return targetLocation;
else
t = t2;
else if (t2 <= 0 || t2 == Mathf.Infinity || float.IsNaN(t2) || t2 > t1)
t = t1;
else
t = t2;
Debug.Log("t = " + t);
Debug.Log("Bs = " + Bs);
float Bvx = (Ax - Bx + (t * As + Avx)) / (t * Mathf.Pow(Bs, 2));
float Bvy = (Ay - By + (t * As + Avy)) / (t * Mathf.Pow(Bs, 2));
float Bvz = (Az - Bz + (t * As + Avz)) / (t * Mathf.Pow(Bs, 2));
Vector3 Bv = new Vector3(Bvx, Bvy, Bvz);
Debug.Log("||Bv|| = (Should be 1) " + Bv.magnitude);
return Bv * Bs;
}
I followed the problem formulation as described by Gil Moshayof's answer, but found that there was an error in the simplification of the quadratic formula. When I did the derivation by hand I got a different solution.
The following is what worked for me when finding the intersect in 2D:
std::pair<double, double> find_2D_intersect(Vector3 sourcePos, double projSpd, Vector3 targetPos, double targetSpd, double targetHeading)
{
double P0x = targetPos.x;
double P0y = targetPos.y;
double s0 = targetSpd;
double V0x = std::cos(targetHeading);
double V0y = std::sin(targetHeading);
double P1x = sourcePos.x;
double P1y = sourcePos.y;
double s1 = projSpd;
// quadratic formula
double a = (s0 * s0)*((V0x * V0x) + (V0y * V0y)) - (s1 * s1);
double b = 2 * s0 * ((P0x * V0x) + (P0y * V0y) - (P1x * V0x) - (P1y * V0y));
double c = (P0x * P0x) + (P0y * P0y) + (P1x * P1x) + (P1y * P1y) - (2 * P1x * P0x) - (2 * P1y * P0y);
double t1 = (-b + std::sqrt((b * b) - (4 * a * c))) / (2 * a);
double t2 = (-b - std::sqrt((b * b) - (4 * a * c))) / (2 * a);
double t = choose_best_time(t1, t2);
double intersect_x = P0x + t * s0 * V0x;
double intersect_y = P0y + t * s0 * V0y;
return std::make_pair(intersect_x, intersect_y);
}

physics: determine velocities of 2 spheres after collision

I'm using Physics for Games Programmers to develop a simple physics-based game.
I need to compute the resulting velocities for two spheres after an elastic collision. The book example for this in Chapter 6 assumes that the 2nd sphere is stationary, and so some of the equations are simplified to 0. I need the math to work when both bodies are in motion.
I've tried to convert the book's example to code, and puzzle out what should happen for the second sphere's line of action and normal- V2p and V2n. My code sort of works, but occasionally the velocities suddenly speed up and bounce out of control. Clearly there's something wrong with my math.
Here's what I'm using. The code is in Java, "s1" and "s2" are the spheres.
double e = 1d;
// distance of sphere centers
double dX = s2.getCenterX() - s1.getCenterX();
double dY = s2.getCenterY() - s1.getCenterY();
double tangent = dY / dX;
double angle = Math.atan(tangent);
// v1 line of action
double v1p = s1.getVelocityX() * Math.cos(angle) + s1.getVelocityY() * Math.sin(angle);
// v1 normal
double v1n = -s1.getVelocityX() * Math.sin(angle) + s1.getVelocityY() * Math.cos(angle);
// v2 line of action
double v2p = s2.getVelocityX() * Math.cos(angle) + s2.getVelocityY() * Math.sin(angle);
// v2 normal
double v2n = -s2.getVelocityX() * Math.sin(angle) + s2.getVelocityY() * Math.cos(angle);
double v1massScale = (s1.getMass() - (e * s2.getMass())) / (s1.getMass() + s2.getMass());
double v2massScale = ((1 + e) * s1.getMass()) / (s1.getMass() + s2.getMass());
// compute post-collision velocities
double v1pPrime = v1massScale * v1p + v2massScale * v2p;
double v2pPrime = v2massScale * v1p + v1massScale * v2p;
// rotate back to normal
double v1xPrime = v1pPrime * Math.cos(angle) - v1n * Math.sin(angle);
double v1yPrime = v1pPrime * Math.sin(angle) + v1n * Math.cos(angle);
double v2xPrime = v2pPrime * Math.cos(angle) - v2n * Math.sin(angle);
double v2yPrime = v2pPrime * Math.sin(angle) + v2n * Math.cos(angle);
It might be the Math.atan(y/x). You need to handle some special cases, and you usually want to use Math.atan2(y,x) instead.
See the Math.atan() and Math.atan2() docs.
It's a surprisingly difficult problem if you don't know much about physics or math.
You need to know about Newton's laws of motion. These are couple differential equations, so you'll need to know how to solve those.
The problem is easier if you assume certain things to be unimportant for the behavior you're interested in: rigid versus deformable spheres, friction, and other factors.
The answer depends a lot on what you'd like to do.
A quick glance at the code you posted suggests that the best you can hope for is that you have a correct but less than optimal implementation. It's likely that you fail to understand the physics and mathematics sufficiently well to solve it on your own.
I'd Google for a physics engine in the language of your choice and use an idealization that someone else has already coded.

Intersection on circle of vector originating inside circle

I have a circle. Inside the circle is a point. I have a vector originating at this point. I'd like to know what point on the circle this vector intersects. Here is a drawing:
http://n4te.com/temp/circle.png http://n4te.com/temp/circle.png
The red dot is the point I am trying to determine.
I know these things: the center of the circle, the origin of the vector, and the direction of the vector.
I know this is basic stuff, but I'm still having trouble. Most of the Googlings bring me to line-circle collision, which is related but not quite the same. Thanks for any help you can provide!
Elementary vector algebra.
O — center of circle (vector)
r — its radius (scalar)
A — origin of ray (vector)
k — direction of ray (vector)
Solve (A + kt - O)² = r² for scalar t, choose positive root, and A + kt is your point.
Further explanation:
. is dot product, ² for a vector is dot product of the vector with itself. Expand LHS
(A + kt - O)² = (A - O)² + 2(k.(A - O))t + k²t².
The quadratic is k²t² + 2(k.(A - O))t + (A - O)² - r² = 0. In terms of your variables, this becomes (rayVX² + rayVY²)t² + 2(rayVX(rayX - circleX) + rayVY(rayY - circleY))t + (rayX - circleX)² + (rayY - circleY)² - r² = 0.
Much thanks to Anton Tykhyy for his detailed answer. This was the resulting Java code:
float xDiff = rayX - circleX;
float yDiff = rayY - circleY;
float a = rayVX * rayVX + rayVY * rayVY;
float b = 2 * (rayVX * (rayX - circleX) + rayVY * (rayY - circleY));
float c = xDiff * xDiff + yDiff * yDiff - r * r;
float disc = b * b - 4 * a * c;
if (disc >= 0) {
float t = (-b + (float)Math.sqrt(disc)) / (2 * a);
float x = rayX + rayVX * t;
float y = rayY + rayVY * t;
// Do something with point.
}

Resources