+8  A: 

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.

Anton Tykhyy
Thanks for the response. It isn't clear to me how to go from your equation to Java code. Can you show how to solve using the following variables?circleX, circleY, radius, rayX, rayY, rayVX, rayVY
NateS
Look up quadratic equation in the math reference of your choice.
starblue
I'm afraid that doesn't help.I don't understand how it works when O, A, and k are two values.([rayX, rayY] + [rayVX, rayVY] * t - [circleX, circleY])² = r²
NateS
You really shouldn't be trying to program geometry without a basic understanding of maths. If either rayVX or rayVY is zero, you've already got a quadratic in one variable; otherwise write one in terms of the other.
Pete Kirkham
What I should or shouldn't be trying to program is irrelevant. While I appreciate you may know the answer and can express it mathematically, I simply need the solution in terms I can understand.
NateS
The notation is a little confusing. A + kt - O is a vector. (A + kt - O)^2 should be computed as (A.x + k * t.x - O.x)^2 + (A.y + k * t.y - O.y)^2=r^2. Expanding this gives a quadratic equation with k as the unknown. I'd assume you know how to solve quadratic equations.
Accipitridae
@NateS: since you were talking about vectors, I assumed you knew about vectors. See en.wikipedia.org/wiki/Euclidean_vector.@Pete: why comment if you don't understand what's going on? The equation already is quadradic in one variable. @Acci: this notation is fairly standard, been using it ever since junior high school.
Anton Tykhyy
+1  A: 

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.
}
NateS