I have a line from the center point of a circle to another point. I want to find the point where the line intersects the circumference of the circle

StackOverflow https://stackoverflow.com/questions/11811660

Question

I have tried several different solutions but no luck so far.

- (CGPoint)contractLineTemp:(CGPoint)point :(CGPoint)circle :(float)circleRadius { 
CGFloat x,y;
x = point.x - circle.x;
y = point.y - circle.y;

CGFloat theta = atan2(x, y);

CGPoint newPoint;

newPoint.x = circle.x + circleRadius * sin(theta);
newPoint.y = circle.y + circleRadius * cos(theta);

return newPoint;
}


- (CGPoint)contractLineTemp:(CGPoint)startPoint :(CGPoint)endPoint :(float)scaleBy {

float dx = endPoint.x - startPoint.x;
float dy = endPoint.y - startPoint.y;

float scale = scaleBy * Q_rsqrt(dx * dx + dy * dy);
return CGPointMake (endPoint.x - dx * scale, endPoint.y - dy * scale);
}

Both of these solutions kind of work. If I draw the line to the center of the circle you can see that it intersects the circle exactly where it should.

http://www.freeimagehosting.net/le5pi

If I use either of the solutions above and draw to the circumference of the circle depending on the angle it is no longer going towards the center of the circle. In the second image the line should be in the middle of the right edge of the circle and going straight right.

http://www.freeimagehosting.net/53ovs

http://www.freeimagehosting.net/sb3b2

Sorry for the links. I am to new to currently post images.

Thanks for you help.

Was it helpful?

Solution

It's easier to treat this as a vector problem. Your second approach is close, but you don't correctly scale the vector between the two points. It's easier to work with a normalized vector in this case, although you have to assume that the distance between the two points on the line is non-zero.

Given:

double x0 = CIRC_X0; /* x-coord of center of circle */
double y0 = CIRC_Y0; /* y-coord of center of circle */

double x1 = LINE_X1; /* x-coord of other point on the line */
double y1 = LINE_Y1; /* y-coord of other point on the line */

Then the vector between the two points is (vx,vy):

double vx = x1 - x0;
double vy = y1 - y0;

It's easier to work with a unit vector, which we can get by normalizing (vx,vy):

double vmag = sqrt(vx*vx + vy*vy);
vx /= vmag;  /* Assumption is vmag > 0 */
vy /= vmag;

Now, any point along the line can be described as:

x0 + dist * vx
y0 + dist * vy

where dist is the distance from the center. The intersection of the circle and the line must be a distance of CIRC_RADIUS from the center, so:

double x_intersect = x0 + CIRC_RADIUS * vx;
double y_intersect = y0 + CIRC_RADIUS * vy;

OTHER TIPS

I think that there may be a convention conflict on what theta, x and y are. The atan2 function yields values in the range -pi..pi, by taking the convention of theta as the angle growing from the X axis towards Y. However you are considering theta as the angle from Y to X. Try changing the code:

CGFloat theta = atan2(y, x);
CGPoint newPoint;
newPoint.x = circle.x + circleRadius * cos(theta);
newPoint.y = circle.y + circleRadius * sin(theta);

Although your formulae are consistent within a coordinate system, it may have conflict with the screen/display device coordinate system.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top