1 Востаннє редагувалося ADR (01.03.2016 11:52:54)

Тема: Пошук точки спряження

То я туплю чи це справді не так вже й просто?

Для початку спряження лінії із колом:
https://habrastorage.org/files/0c6/f0a/60b/0c6f0a60baa74c349729660e795452c2.png
Тут, ніби, більше-менш просто — задаємо умову типу: хочу точку B(x, y), яка буде віддалена на такий-то радіус від точки O і на такий-то радіус від точки A. І отримуємо довге, квадратне рівняння із двома можливими розв'язками.

Але що робити коли потрібно зробити спряження двох кіл?
https://habrastorage.org/files/b1a/952/792/b1a952792c6942e9a826d766d7c68061.png
Єдиний варіант це навчитись розв'язувати кубічне рівняння, систему рівнянь і вибирати потрібний результат?

Можна якось ввести у формулу обмеження, які б вибрали лише один із результатів і спростили б формулу?

2

Re: Пошук точки спряження

Ви про дотичні прямі кажете? Знайти спільну дотичну до двох кіл?

3

Re: Пошук точки спряження

koala написав:

Ви про дотичні прямі кажете? Знайти спільну дотичну до двох кіл?

Так

4

Re: Пошук точки спряження

Як шукати зовнішні дотичні (CD і EF):
Для початку припустимо, що ми їх вже знайшли і пошукаємо цікаві співвідношення. Отже, в чотирикутнику O1O2DC:
- O1O2 відоме (позначимо його d - від distance, відстань між центрами);
- O2D відоме (позначимо його r2);
- O1C відоме (позначимо його r1);
- Кути O1CD та O2DC прямі (бо між радіусом і дотичною).
Отже, маємо прямокутну трапецію з 3 відомими сторонами. Проведемо пряму з O2 до перетину X з O1C. Маємо прямокутний трикутник O2XO1, в якому O2X = r1-r2, O2O1=d, кут X прямий. З нього можна знайти кути O1=α і O2=β.
Тепер побудуємо на нашому малюнку кут O2O1C=α. Точка перетину O1C з колом - це і є точка C. Від C відкладемо CX=r і проведемо через X пряму XO2, а потім паралельну їй CD. Дотична побудована.

Подякували: ADR, leofun012

5

Re: Пошук точки спряження

Із зовнішніми ще легше: поділимо O1O2 у співвідношенні r1:r2. Доведіть, що отримана точка є точкою перетину внутрішніх дотичних, самостійно.
До речі, із зовнішніми теж можна такий фокус зробити - знайти за співвідношенням радіусів точку перетину дотичних, тільки зараз збагнув, що так легше...

Подякували: ADR, leofun012

6

Re: Пошук точки спряження

Може комусь треба буде:
(реалізація на Python)

import math

def get_intersection_of_circle(x0, y0, r0, x1, y1, r1):
    # http://paulbourke.net/geometry/circlesphere/
    # http://paulbourke.net/geometry/circlesphere/tvoght.c

    dx = x1 - x0
    dy = y1 - y0
    d = math.sqrt(dx ** 2 + dy ** 2)

    if d > r0 + r1:
        raise Exception("No solution! Circles do not intersect!")
    if d < abs(r0 - r1):
        raise Exception("No solution! One circle is contained in the other!")

    a = (r0 ** 2 - r1 ** 2 + d ** 2) / (2 * d)

    x2 = x0 + (dx * a / d)
    y2 = y0 + (dy * a / d)

    h = math.sqrt(r0 ** 2 - a ** 2)

    rx = - dy * (h / d)
    ry = dx * (h / d)

    return (x2 - rx, y2 - ry), (x2 + rx, y2 + ry)


def get_line_coefficients(x0, y0, x1, y1):
    b = (y1 - y0) / (x1 - x0)
    a = y0 - b * x0

    return a, b     # y(x) = a + b * x


def get_tangent_lines_to_one_circle(x0, y0, r0, x1, y1):
    # https://goo.gl/1fAzhc
    if np.isclose(x0, x1):
        raise Exception("Don't work for x0 = x1!")

    a, b = get_line_coefficients(x0, y0, x1, y1)
    middle_x = (x0 + x1) / 2
    return get_intersection_of_circle(x0, y0, r0,
                                       middle_x,
                                       a + b * middle_x,
                                       math.sqrt((x0 - x1) ** 2 + (y0 - y1) ** 2) / 2)


def get_inner_tangent_lines_to_two_circle(x0, y0, r0, x1, y1, r1):
    points = get_tangent_lines_to_one_circle(x0, y0, r0 + r1, x1, y1)

    result = []
    for point in points:
        a2, b2 = get_line_coefficients(*point, x0, y0)
        x2 = point[0] + (x0 - point[0]) * (r1 / (r0 + r1))
        y2 = a2 + b2 * x2
        x3 = x1 + (x2 - point[0])
        y3 = y1 + (y2 - point[1])

        result.append(((x2, y2), (x3, y3)))

    return result
Подякували: leofun011