10
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

点から円への接点を求める

Last updated at Posted at 2020-04-10

円に対する点の位置と接線の関係

  • 点が円の外側にあるとき ・・・ 接線は2本
  • 点が円周上にあるとき  ・・・ 接線は1本
  • 点が円の内部にあるとき ・・・ 接線は存在しない

円の接線の方程式

円 $x^2+y^2=r^2$ の円周上の1点 $P(x_0,y_0)$ を通る接線の方程式を求める。

$P$ を通る円の接線は半径 $OP$ に垂直。
$OP$ の傾きは $\dfrac{y_0}{x_0}$ なので、接線の傾きを $m$ とすると、
$$\dfrac{y_0}{x_0}m=-1\ \ \ \ \ \ \therefore\ m=-\frac{x_0}{y_0}$$
となる。
したがって、この接線は点 $(x_0,y_0)$ を通る傾きが $-\dfrac{x_0}{y_0}$の直線で、その方程式は、
$$y-y_0=-\dfrac{x_0}{y_0}(x-x_0)$$
です。(直線の方程式 参照)
この式の両辺に $y_0$ を掛けると、
$$y_0(y-y_0)=-\frac{x_0(x-x_0)y_0}{y_0}$$
$$y_0y-y_0^2=-x_0x+x_0^2$$
となり、$-x_0x$ を左辺に $-y_0^2$ を右辺に移項すると、
$$x_0x+y_0y=x_0^2+y_0^2$$
また、点 $P(x_0,y_0)$ は円 $x^2+y^2=r^2$ の円周上の点なので、
$$x_0^2+y_0^2=r^2$$
が成り立つ。したがって、接線の方程式は
$$x_0x+y_0y=r^2$$
となる。
また、中心の座標が $(a,b)$ 半径が $r$ の円 $(x-a)^2+(y-b)^2=r^2$ おいて、円周上の点$P(x_0,y_0)$ を通る接線の方程式は、
$$(x_0-a)(x-a)+(y_0-b)(y-b)=r^2$$
です。

【例】中心(3,2) 半径 5 の円の円周上の点 (6,6) を通る接線の方程式を求める

接線の方程式 $(x_0-a)(x-a)+(y_0-b)(y-b)=r^2$ より、
$(6-3)(x-3)+(6-2)(y-2)=5^2\ \dashrightarrow \ 6\cdot(x-3)+4\cdot(y-2)=25\ \dashrightarrow \ 6x-18+4y-8-25=0$
よって接線の方程式は、
$$6x+4y-42=0$$

極線の方程式

円 $x^2+y^2=r^2$ と円外の点 $Q(x_1,y_1)$ について、点 $Q$ から円には2つの接線が引ける。
その接線の接点をそれぞれ $A,B$ としたときの直線 $AB$ の方程式を求める。
この直線 $AB$ を円の極線、点 $Q$ のことを円のという。

点 $A$ の座標を $(x_a,y_a)$、点 $B$ の座標を $(x_b,y_b)$ をしたとき、
点 $A,B$ を通る円の接線の方程式はそれぞれ、
$$x_ax+y_ay=r^2$$
$$x_bx+y_by=r^2$$
となる。この接線が 点 $Q(x_1,y_1)$ を通るので、
$$x_ax_1+y_ay_1=r^2 \ \cdots \ ①$$
$$x_bx_1+y_by_1=r^2 \ \cdots \ ②$$
となる。この2つの式をよく見ると、

  • ①は、式 $x_1x+y_1y=r^2$ の $x,y$ に点$A$ の座標 $(x_a,y_a)$ を代入した式
  • ②は、式 $x_1x+y_1y=r^2$ の $x,y$ に点$B$ の座標 $(x_b,y_b)$ を代入した式

になっている。
異なる2点を通る直線は一意に定まるので、この2つの式①②が成り立つをいうことは、
直線 $AB$ の方程式が $x_1x+y_1y=r^2$ であるということを示している。
よって直線 $AB$ の方程式は、
$$x_1x+y_1y=r^2$$
これが円 $x^2+y^2=r^2$ と円外の点 $Q(x_1,y_1)$ に関する極線の方程式です。

また、中心が $(a,b)$ 半径が $r$ の円 $(x-a)^2+(y-b)^2=r^2$ とその円外の点 $(x_1,y_1)$ に関する極線の方程式は、
中心が $(0,0)$ の円の場合より、$x$ 軸方向に $-a$、$y$ 軸方向に $-b$ 平行移動した円と考えられるので、
その方程式は、
$$(x_1-a)(x-a)+(y_1-b)(y-b)=r^2$$
となる。

点から円への接点を求める

中心が $(x_0,y_0)$ 半径が $r$ の円 $(x-x_0)^2+(y-y_0)^2=r^2$ とその円外の点 $Q(x_1,y_1)$ の接線の2つの接点 $A,B$ の座標を求める。

求め方

円と円外の点 $Q(x_1,y_1)$ に関する極線の方程式を求めて、その極線と円の交点を、円と直線の交点を求める公式を使って求める。

極線 $AB$ の方程式は、
$$(x_1-x_0)(x-x_0)+(y_1-y_0)(y-y_0)=r^2$$
この式を展開して、
$x_1x-x_1x_0-x_0x+x_0^2+y_1y-y_1y_0-y_0y+y_0^2-r^2=0$
整理すると、
$$(x_1-x_0)x+(y_1-y_0)y+(x_0^2+y_0^2-x_1x_0-y_1y_0-r^2)=0 \ \cdots \ ①$$
この式は、直線の方程式の一般形 $ax+by+c=0$ の係数$a,b,c$をそれぞれ、

  • $a=(x_1-x_0)$
  • $b=(y_1-y_0)$
  • $c=(x_0^2+y_0^2-x_1x_0-y_1y_0-r^2)$

とした形になっている。

中心の座標が $(x_0,y_0)$ 半径 $r$ の円 $(x-x_0)^2+(y-y_0)^2=r^2$ と直線 $ax+by+c=0$ の交点を求める公式は、交点を $A,B$ とした場合、(円と直線の交点を求める 参照)
$$A=\left(\frac{aD-b\sqrt{(a^2+b^2)r^2-D^2}}{a^2+b^2}+x_0,\frac{bD+a\sqrt{(a^2+b^2)r^2-D^2}}{a^2+b^2}+y_0\right) \ \cdots \ ②$$
$$B=\left(\frac{aD+b\sqrt{(a^2+b^2)r^2-D^2}}{a^2+b^2}+x_0,\frac{bD-a\sqrt{(a^2+b^2)r^2-D^2}}{a^2+b^2}+y_0\right) \ \cdots \ ③$$
$$ただし、D=\mid ax_0+by_0+c\mid$$
で、この $D$ の式に、① の係数 $a,b,c$ にあたる値を代入すると、
$D=\mid ax_0+by_0+c\mid=\mid (x_1-x_0)x_0+(y_1-y_0)y_0+(x_0^2+y_0^2-x_1x_0-y_1y_0-r^2)\mid$
$=\mid x_1x_0-x_0^2+y_1y_0-y_0^2+x_0^2+y_0^2-x_1x_0-y_1y_0-r^2\mid=\mid -r^2 \mid=r^2$
つまり、
$$D=r^2$$
これを②③に代入すると、
$$A=\left(\frac{ar^2-b\sqrt{(a^2+b^2)r^2-(r^2)^2}}{a^2+b^2}+x_0,\frac{br^2+a\sqrt{(a^2+b^2)r^2-(r^2)^2}}{a^2+b^2}+y_0\right)$$
$$=\left(r\cdot\frac{ar-b\sqrt{a^2+b^2-r^2}}{a^2+b^2}+x_0,r\cdot\frac{br+a\sqrt{a^2+b^2-r^2}}{a^2+b^2}+y_0\right) \ \cdots \ ④$$
$$B=\left(\frac{ar^2+b\sqrt{(a^2+b^2)r^2-(r^2)^2}}{a^2+b^2}+x_0,\frac{br^2-a\sqrt{(a^2+b^2)r^2-(r^2)^2}}{a^2+b^2}+y_0\right)$$
$$=\left(r\cdot\frac{ar+b\sqrt{a^2+b^2-r^2}}{a^2+b^2}+x_0,r\cdot\frac{br-a\sqrt{a^2+b^2-r^2}}{a^2+b^2}+y_0\right) \ \cdots \ ⑤$$
式④⑤の $a,b$ に、① の係数 $a,b$ にあたる値を代入すると、
$$A=\left(r\cdot\frac{(x_1-x_0)r-(y_1-y_0)\sqrt{(x_1-x_0)^2+(y_1-y_0)^2-r^2}}{(x_1-x_0)^2+(y_1-y_0)^2}+x_0,
r\cdot\frac{(y_1-y_0)r+(x_1-x_0)\sqrt{(x_1-x_0)^2+(y_1-y_0)^2-r^2}}{(x_1-x_0)^2+(y_1-y_0)^2}+y_0\right)$$
$$B=\left(r\cdot\frac{(x_1-x_0)r+(y_1-y_0)\sqrt{(x_1-x_0)^2+(y_1-y_0)^2-r^2}}{(x_1-x_0)^2+(y_1-y_0)^2}+x_0,r\cdot\frac{(y_1-y_0)r-(x_1-x_0)\sqrt{(x_1-x_0)^2+(y_1-y_0)^2-r^2}}{(x_1-x_0)^2+(y_1-y_0)^2}+y_0\right)$$
となる。
これが、円 $(x-x_0)^2+(y-y_0)^2=r^2$ とその円外の点 $Q(x_1,y_1)$ の接線の2つの接点 $A,B$ の座標を求める公式です。

【例】中心(3,2) 半径 5 の円に対して、点 (15,5) から引いた2つの接線の接点を求める。

上記公式より、 $x_1-x_0=15-3=12\ \ \ \,\ \ \ \ y_1-y_0=5-2=3$ 点 $A$ の $x$ 座標 $x_a$ は、 $$x_a=5\cdot\frac{12\cdot5-3\sqrt{12^2+3^2-5^2}}{12^2+3^2}+3=\frac{253-40\sqrt{2}}{51}\fallingdotseq 3.851597$$ 点 $A$ の $y$ 座標 $y_a$ は、 $$y_a=5\cdot\frac{3\cdot5+12\sqrt{12^2+3^2-5^2}}{12^2+3^2}+2=\frac{127+160\sqrt{2}}{51}\fallingdotseq 6.926945$$ 点 $B$ の $x$ 座標 $x_b$ は、 $$x_b=5\cdot\frac{12\cdot 5+3\sqrt{12^2+3^2-5^2}}{12^2+3^2}+3=\frac{253+40\sqrt{2}}{51}\fallingdotseq 6.069971$$ 点 $B$ の $y$ 座標 $y_b$ は、 $$y_b=5\cdot\frac{3\cdot 5-12\sqrt{12^2+3^2-5^2}}{12^2+3^2}+2=\frac{127-160\sqrt{2}}{51}\fallingdotseq -1.946552$$ よって、接点 $A,B$ の座標は、 $$A=\left(\frac{253-40\sqrt{2}}{51},\frac{127+160\sqrt{2}}{51}\right)\fallingdotseq (3.851597,6.926945)$$ $$B=\left(\frac{253+40\sqrt{2}}{51},\frac{127-160\sqrt{2}}{51}\right)\fallingdotseq (6.069971,-1.946552)$$ となる。

サンプルプログラム

円図形を選択して、その次に点を指示。その点から選択した円への2つの接線を作成して、その接点の座標を出力する

;; 点から円への接線を作成して、その接点の座標を出力する
(defun c:CreateCircleTangent (/ circle point n)
    ;; 円を選択
    (while (null circle)
        (setvar 'ERRNO 0)
        (setq circle (car (entsel "円を選択: ")))
        (cond
            ;; 空振り
            (   (= 7 (getvar 'ERRNO))
                (princ "\n**空振り!!再選択**\n")
                (setq circle nil)
            )
            ;; 空Enter
            (   (= 52 (getvar 'ERRNO))
                (princ "\n**空Enter!!再選択**\n")
                (setq circle nil)
            )
            ;; 図形が選択された
            (circle
                (if (/= "CIRCLE" (entity:GetType circle))
                    (progn
                        (princ "\n**円ではありません!!再選択**\n")
                        (setq circle nil)
                    )
                    (princ "\n**円が選択されました。**\n")
                )
            )
        )
    )
    ;; 点を選択
    (while (null point)
        (setq point (getpoint "点を指示: " ))
        (if point
            (if (circle:IsOnOrContains circle point)
                (progn
                    (princ "\n**円の内部の点です!!再選択**\n")
                    (setq point nil)
                )
	        (princ "\n**点が指示されました。**\n")
            )
        )
    )
    (setq n 1)
    (mapcar
        (function
            (lambda (tp)
                (princ (strcat "\n接点の座標" (itoa (setq n (1+ n))) ":"))
                (entmake:2PointsXline point (princ tp)) ;_構築線を作成
            )
        )
        (circle:GetTangentPoints circle point) ;_接点を計算
    )
    (princ)
)

;; == sub functions ==
;; 図形のDXF定義データの値を取得
(defun entity:GetDxf (g e)
    (cond
        ((= (type e) 'ENAME) (cdr (assoc g (entget e))))
        ((listp e) (cdr (assoc g e)))
    )
)
;; 図形のタイプを取得
(defun entity:GetType (e) (entity:GetDxf 0 e))
;; 円の中心を取得
(defun circle:GetCenterPoint (e) (entity:GetDxf 10 e))
;; 円の半径を取得
(defun circle:GetRadius (e) (entity:GetDxf 40 e))
;; 円周上の点か調べる
(defun circle:IsOnBase (cx cy cr x y)
    (equal (+ (expt (- x cx) 2) (expt (- y cy) 2)) (* cr cr) 1e-8)
)
(defun circle:IsOn (circle point / r o)
    (setq r (circle:GetRadius circle) o (circle:GetCenterPoint circle))
    (circle:IsOnBase (car o) (cadr o) r (car point) (cadr point))
)
;; 円の内部の点か調べる
(defun circle:ContainsBase (cx cy cr x y)
    (< (+ (expt (- x cx) 2) (expt (- y cy) 2)) (* cr cr))
)
(defun circle:Contains (circle point / r o)
    (setq r (circle:GetRadius circle) o (circle:GetCenterPoint circle))
    (circle:ContainsBase (car o) (cadr o) r (car point) (cadr point))
)
;; 円の内部の点か調べる 円周上の点も含める
(defun circle:IsOnOrContains (circle point)
    (or (circle:IsOn circle point) (circle:Contains circle point))
)
;; 円の接点を求める
(defun circle:GetTangentPoints (circle point / a b c d r o)
    (setq r (circle:GetRadius circle)
          o (circle:GetCenterPoint circle)
          a (- (car point) (car o))
          b (- (cadr point) (cadr o))
          c (+ (* a a) (* b b))
          d (sqrt (- c (* r r)))
    )
    (list
        (list
            (+ (/ (* r(- (* a r) (* b d))) c) (car o))
            (+ (/ (* r(+ (* b r) (* a d))) c) (cadr o))
        )
        (list
            (+ (/ (* r(+ (* a r) (* b d))) c) (car o))
            (+ (/ (* r(- (* b r) (* a d))) c) (cadr o))
        )
    )
)
;; 構築線の基本DXF定義
(defun entmake:XlineBase (p u)
    (list '(000 . "XLINE")
          '(100 . "AcDbEntity")
          '(100 . "AcDbXline")
          (cons 010 p)
          (cons 011 u)
    )
)
;; 基点と単位方向ベクトルから構築線を作成
(defun entmake:Xline (p u) (entmake (entmake:XlineBase p u)) (entlast))
;; 2点を結ぶベクトルの成分を計算
(defun vector:From2Points (p q) (mapcar '- q p))
;; ベクトル から 単位ベクトルを計算
(defun vector:ToUnitVector (v)
    (   (lambda (n)
            (if (equal 0.0 n 1e-10)
                nil
                (mapcar '/ v (list n n n))
            )
        )
        (distance '(0. 0. 0.) v)
    )
)
;; 2点から単位ベクトルを計算
(defun vector:2PointsToUnitVector (p q) (vector:ToUnitVector (vector:From2Points p q)))
;; 2点指示で構築線を作成
(defun entmake:2PointsXline (a b)
    (entmake:Xline a (vector:2PointsToUnitVector a b))
)

点から円への接線を作図する

中心が $(x_0,y_0)$ 半径が $r$ の円 $(x-x_0)^2+(y-y_0)^2=r^2$ とその円外の点 $Q(x_1,y_1)$ の2つの接線を作図する。

  1. 点 $C$ 、点 $Q$ の中点をとる
  2. その中点を中心とした、線分$CQ$を直径とする円を作図する
  3. その作図した円と円 $(x-x_0)^2+(y-y_0)^2=r^2$ の2つの交点 $A,B$と点 $Q(x_1,y_1)$を通る直線をそれぞれ作図する
  4. その2つの直線が点から円への接線(半円の弧に対する円周角は直角)
10
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?