简体   繁体   English

如何计算切点的坐标?

[英]How to calculate coordinates of tangent points?

I need to make a svg file for a project and I need some parameters that I haven't figured out how to calculate yet.我需要为一个项目制作一个 svg 文件,我需要一些我还没有弄清楚如何计算的参数。 I have a point of coordinates x1,y1 and a circumference with a center of coordinates x2,y2 with radius r .我有一个坐标点x1,y1和一个以坐标x2,y2为中心、半径为r的圆周。 The point x1,y1 is outside the circumference.点 x1,y1 在圆周外。 How do I calculate the coordinates of the points belonging to the circumference ( x3,y3 and x4,y4 ) from which the two tangent lines would pass?如何计算属于圆周( x3,y3x4,y4 )的点的坐标,两条切线将从中通过? The outer point (x1,y1) will never touch the circumference and will never belong to the circumference.外点 (x1,y1) 永远不会接触到圆周,也永远不会属于圆周。 This is the drawing to make the concept better understood, in red the values to be calculated.这张是为了更好地理解这个概念,用红色表示要计算的值。 Tangents scheme切线方案

Shift coordinate system to make origin in circle center (to get simpler equations).移动坐标系以使原点位于圆心(以获得更简单的方程式)。 Now point is现在重点是

 x1' = x1 - x2
 y1' = y1 - y2

Solve the next equation system (point belongs to circumference and radius is perpendicular to tangent)求解下一个方程组(点属于圆周,半径垂直于切线)

x^2 + y^2 = r^2
(x - x1') * x + (y - y1') * y = 0

for unknown x, y.对于未知的 x, y。

To get final result, add x2, y2 to solution results (should be two solutions)要获得最终结果,请将x2, y2添加到解决方案结果(应该是两个解决方案)

import math
def tangpts(px, py, cx, cy, r):
    px -= cx
    py -= cy
    r2 = r*r
    r4 = r2*r2
    a = px*px+py*py
    b = -2*r2*px
    c = r4 - r2*py*py
    d = b*b-4*a*c
    if d < 0:
        return None
    d = math.sqrt(d)
    xx1 = (-b - d) / (2*a)
    xx2 = (-b + d) / (2*a)
    if (abs(py) > 1.0e-8):
        yy1 = (r2 - px * xx1) / py
        yy2 = (r2 - px * xx2) / py
    else:
        yy1 = math.sqrt(r2 - xx1*xx1)
        yy2 = -yy1

    return((xx1+cx,yy1+cy),(xx2+cx,yy2+cy))

print(tangpts(0.5, 0.5, 0, 0, 1))
print(tangpts(1, 1, 0, 0, 1))
print(tangpts(0, 0, -3, -3, 3))
print(tangpts(2, 0, 0, 0, 1))
print(tangpts(0, 1, 0, 0, 1))

>>>
None             #point inside 
((0.0, 1.0), (1.0, 0.0))    #common case
((-3.0, 0.0), (0.0, -3.0))   #common case
((0.5, 0.8660254037844386), (0.5, -0.8660254037844386))   #py is zero case
((0.0, 1.0), (0.0, 1.0))  # single tangent case - point at circumference

In order to post the python code for the solution, I'm copying the explanation originally in comments:为了发布解决方案的 python 代码,我复制了最初在评论中的解释:

  1. The center of the circle is P 2 (x2, y2), the radius is r. The unknown point P 3 (x3, y3) satisfies the equation of the circle:圆心为P 2 (x2,y2),半径为r。未知点P 3 (x3,y3)满足圆的方程:

    (x3-x2)^2 + (y3-y2)^2 = r^2 (1) . (x3-x2)^2 + (y3-y2)^2 = r^2 (1)

  2. The tangent P 1 P 3 is perpendicular to the radius of the circle P 2 P 3 .切线 P 1 P 3垂直于圆 P 2 P 3的半径。 So apply the Pythagorean theorem to the triangle P 1 P 2 P 3 :因此,将勾股定理应用于三角形 P 1 P 2 P 3

    a) the distance between P 1 and P 2 is (x1-x2)^2 + (y1-y2)^2, a) P 1和 P 2之间的距离是 (x1-x2)^2 + (y1-y2)^2,

    b) the distance between P 1 and P 3 is (x1-x3)^2 + (y1-y3)^2 b) P 1和 P 3之间的距离是 (x1-x3)^2 + (y1-y3)^2

    c) the distance P 2 P 3 is r, the radius c) 距离P 2 P 3为r,半径

    (x1-x3)^2 + (y1-y3)^2 + r^2 = (x1-x2)^2 + (y1-y2)^2 (2) (x1-x3)^2 + (y1-y3)^2 + r^2 = (x1-x2)^2 + (y1-y2)^2 (2)

We have thus to solve the equations (1) and (2) for x3 and y3.因此,我们必须针对 x3 和 y3 求解方程式 (1) 和 (2)。

We now separate the unknowns (a linear relation between x3 and y3 can be obtained by (1)-(2) => (x3-x2)(x1-x2) + (y3-y2)(y1-y2) = r^2 ), and we get the two equations of second degree.我们现在分离未知数(x3 和 y3 之间的线性关系可以通过 (1)-(2) => (x3-x2)(x1-x2) + (y3-y2)(y1-y2) = r^ 2 ), 得到两个二次方程.

The python implementation: python 实现:

import math
def tangentPoints(x1, y1, x2, y2, r):
  a = (y1-y2)**2+(x1-x2)**2
  bx = -r**2 * (x1-x2)
  cx = r**2 * (r**2-(y1-y2)**2)
  sqDeltax = math.sqrt(bx**2 - a*cx)
  x3 = x2 + (-bx + sqDeltax)/a
  x4 = x2 + (-bx - sqDeltax)/a
  
  by = -r**2 * (y1-y2)
  cy = r**2 * (r**2 - (x1-x2)**2)
  sqDeltay = math.sqrt(by**2 - a*cy)
  y3 = y2 + (-by - sqDeltay)/a
  y4 = y2 + (-by + sqDeltay)/a

  return (x3, y3), (x4, y4)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM