Jump to content
  • Advertisement
Sign in to follow this  
swiftcoder

tangents to a circle through a point

This topic is 3732 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I haven't had much luck searching the internet for code to find the tangents to a circle, which pass though a external point, so i wrote this one up:
def find_tangents_through_point(circle_center, circle_radius, point):
	#find the direction from the point to the center of the circle
	dir = point - circle_center
	#extract the length and angle
	len = dir.length
	angle = atan2(dir.y, dir.x)
	
	# derive the length of the tangent using pythagoras
	tangent_len = sqrt(len**2 + circle_radius**2)
	# and the angle using trigonometry
	tangent_angle = atan(circle_radius/len)
	
	# there are 2 tangents, one either side
	pos = angle + tangent_angle
	neg = angle - tangent_angle
	
	#return the direction vector of each tanget (the starting point was passed in)
	return ( vec2d(cos(pos), sin(pos)), vec2d(cos(neg), sin(neg)) )
Unfortunately, it seems to have some accuracy problems:
find_tangents_through_point( vec2d(0,0), 2.0, vec2d(2.0,2.0) )
yields:
vec2d(0.169101983309, 0.985598564148), vec2d(0.985598564148, 0.169101983309)
instead of the expected (0, 1), (1, 0). Any ideas where the inaccuracy is coming from? Am I doing something silly re floating point error?

Share this post


Link to post
Share on other sites
Advertisement
Ah, I see where I went wrong: I assumed that a line connecting the pair of tangent points would pass through the center of the circle, which is clearly not the case.

So, back to the drawing board. Does anyone have a link/explanation of how to find these 'horizon' points?

Share this post


Link to post
Share on other sites
Argh, not my day for thinking things out. I now realise that I had rotated the triangle in my mind, and placed the right angle at the center, rather than at the tangent point :)

In case anybody wants it, the working version (note that tangent_len is the distance from the point to the tangent point):
def find_tangents_through_point(circle_center, circle_radius, point):
#find the direction from the point to the center of the circle
dir = point - circle_center
#extract the length and angle
len = dir.length
angle = atan2(dir.y, dir.x)

# derive the length of the tangent using pythagoras
tangent_len = sqrt(len**2 - circle_radius**2)
# and the angle using trigonometry
tangent_angle = asin(circle_radius/len)

# there are 2 tangents, one either side
pos = angle + tangent_angle
neg = angle - tangent_angle

#return the direction vector of each tanget (the starting point was passed in)
return ( vec2d(cos(pos), sin(pos)), vec2d(cos(neg), sin(neg)) )

Share this post


Link to post
Share on other sites
The key truth to note here is that the vector from your outside point to your tangent point forms a right angle with the vector from your tangent point to the center of your circle.

Definitions: r=radius of circle, A=center of circle, B=outside point, C=one tangent point, |AB|=length from A to B

So, using Pythagoras, you can find that |BC| = sqrt(|AB|^2 - r^2).

So now you have a right triangle, and you know the lengths of all three sides and the locations of two of the points (A and B). Finding the two possible locations of the third point yields your two tangent points.

Share this post


Link to post
Share on other sites
Quote:
Original post by swiftcoder
Ah, I see where I went wrong: I assumed that a line connecting the pair of tangent points would pass through the center of the circle, which is clearly not the case.

Which is actually quite impossible [grin] I'm surprised that your code didn't somehow divide by zero, or implode the universe, or do some other horrible thing!

Share this post


Link to post
Share on other sites
Quote:
Original post by Zipster
Quote:
Original post by swiftcoder
Ah, I see where I went wrong: I assumed that a line connecting the pair of tangent points would pass through the center of the circle, which is clearly not the case.

Which is actually quite impossible [grin] I'm surprised that your code didn't somehow divide by zero, or implode the universe, or do some other horrible thing!
Well, it wasn't so bad. Basically I was just calculating secant lines (lower figure) instead of tangent lines (upper figure):



Share this post


Link to post
Share on other sites
You should also be able to use differential equations here:

Nevermind that, it was a complete disaster. I need to redo it.

[Edited by - Jkom329 on July 2, 2008 5:50:12 PM]

Share this post


Link to post
Share on other sites
Quote:
Original post by Jkom329
You should also be able to use differential equations here...
That looks about right to me, I might re-implement it that way if it shows up in the profiler :)

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!