22from __future__ import absolute_import
33from __future__ import division
44
5- import math
5+ from math import sqrt
66
77
88__all__ = ["tangent_points_to_circle_xy" ]
@@ -14,7 +14,7 @@ def tangent_points_to_circle_xy(circle, point):
1414 Parameters
1515 ----------
1616 circle : [plane, float] | :class:`~compas.geometry.Circle`
17- center, radius of the circle in the xy plane .
17+ Plane and radius of the circle.
1818 point : [float, float] or [float, float, float] | :class:`~compas.geometry.Point`
1919 XY(Z) coordinates of a point in the xy plane.
2020
@@ -26,25 +26,33 @@ def tangent_points_to_circle_xy(circle, point):
2626 Examples
2727 --------
2828 >>> from compas.geometry import allclose
29- >>> circle = (0, 0, 0), 1.0
29+ >>> circle = (( 0, 0, 0), (0, 0, 1) ), 1.0
3030 >>> point = (2, 4, 0)
3131 >>> t1, t2 = tangent_points_to_circle_xy(circle, point)
3232 >>> allclose(t1, [-0.772, 0.636, 0.000], 1e-3)
3333 True
3434 >>> allclose(t2, [0.972, -0.236, 0.000], 1e-3)
3535 True
3636 """
37- m , r = circle [0 ], circle [1 ]
38- cx , cy = m [0 ], m [1 ]
39- px = point [0 ] - cx
40- py = point [1 ] - cy
37+ plane , R = circle
38+ center , _ = plane
4139
42- a1 = r * ( px * r - py * math . sqrt ( px ** 2 + py ** 2 - r ** 2 )) / ( px ** 2 + py ** 2 )
43- a2 = r * ( px * r + py * math . sqrt ( px ** 2 + py ** 2 - r ** 2 )) / ( px ** 2 + py ** 2 )
40+ cx , cy = center [: 2 ]
41+ px , py = point [: 2 ]
4442
45- b1 = ( r ** 2 - px * a1 ) / py
46- b2 = ( r ** 2 - px * a2 ) / py
43+ dx = px - cx
44+ dy = py - cy
4745
48- p1 = [a1 + cx , b1 + cy , 0 ]
49- p2 = [a2 + cx , b2 + cy , 0 ]
50- return p1 , p2
46+ D = sqrt (dx ** 2 + dy ** 2 )
47+ L2 = D ** 2 - R ** 2
48+
49+ a = dx / D , dy / D
50+ b = - a [1 ], a [0 ]
51+
52+ A = D - L2 / D
53+ B = sqrt (R ** 2 - A ** 2 )
54+
55+ t1 = cx + A * a [0 ] + B * b [0 ], cy + A * a [1 ] + B * b [1 ], 0
56+ t2 = cx + A * a [0 ] - B * b [0 ], cy + A * a [1 ] - B * b [1 ], 0
57+
58+ return t1 , t2
0 commit comments