Obliczenie wsółrzędnych środka okręgu

0

Witam,

muszę w c/c++ obliczyć współrzędne środka okręgu (C) mając współrzędne 2 punktów(A,B), które należą na tym okręgu oraz długość promienia R. Wiem, że są dwa takie okręgi. Próbowałem to sprowadzić do problemu wyliczenia 3 wierzchołka trójkąta równoramiennego.

Punkt S jest środkiem odcinka AB. Obliczyć łatwo. Kąt ASB jest kątem prostym, więc z twierdzenia Pitagorasa obliczam długość odcinka SC.

Wzór na prostą przechodzącą przez 2 punkty można obliczyć z układu równań:
y1=x1a+b
y2=x2a+b

przekształcając ten wzór (pierwszy pomnożyłem przez minus jeden i dodałem stronami) doszedłem do tego, że
a= (y2-y1)/(x2-x1)
te 4 dane mam, więc obliczam a, następnie b. Wzór na prostą przechodzącą przez punkt A oraz B znalazłem:)
Z tego obliczę wzór na prostą prostopadłą przechodzącą przez punkt S (czyli środek odcinka AB).

I w tym momencie stanąłem. Chciałem dojść do tego, aby punkt S przesunąć o jakiś wektor, aby dojść do punktu C, ale nie mam pojęcia jak do tego dojść. Macie jakieś pomysły? Może jest prostszy sposób, aby to obliczyć?

W załączniku dodaję ilustrację pomocniczą

0

A nie prościej rozwiązać układ dwóch równań? Piszesz równania okręgów o promieniu R i środku A lub B.
(x-Ax)2 + (y-Ay)2 = R2

0

no tak, ale nie wiem jak takie układy równań rozwiązywać w c/c++ to kombinowałem trochę inaczej

0

Równań nie rozwiązuje się w języku programowania, tylko na kartce ;). Odejmij równania stronami, dostaniesz związek liniowy między x i y, wyznacz y, wstaw do jednego z równań i dostaniesz równanie kwadratowe.

0

nie za bardzo rozumiem

0

Chodzi chyba o doprowadzenie jednego z równań do postaci y=[cośtam]x, i podstawieniu [cośtam]x zamiast y do drugiego równania. Wtedy będziesz miał jedno równanie z jedną niewiadomą.

0

to to wiem, ale jak to zrobić?

Jeśli nawet nie chcesz samemu liczyć, w google jest pełno gotowych algorytmów (https://www.google.pl/search?q=punkty+przecięcia+okręgów+algorytm), jest o tym w Algorytmice Praktycznej Stańczyka, itd, itd.

0

@sig, o to właśnie chodzi.
(x-Ax)2 + (y-Ay)2 = R2
po podniesieniu do kwadratu:
x2 - Ax*x + x2 + y2 - Ay*y + y2 = R2
x2 - Bx*x + x2 + y2 - Byy + y2 = R2
x2 - 2
Axx + Ax2 + y2 - 2Ayy + Ay2 = R2
x2 - 2
Bxx + Bx2 + y2 - 2Byy + By2 = R2
po odjęciu stronami:
- 2
Axx - 2Ayy + 2Bxx + 2By*y = 0</del>

  • 2*Axx - 2Ayy + Ax2 + Ay2 + 2Bxx + 2By*y - Bx2 - By2 = 0
    wyznaczasz y z tego równania i wstawiasz do jednego z równań kwadratowych.
0

wektor od S do A
V = SA

odległość punku S od środka okręgu
k=sqrt(R^2-V^2) (z pitagorasa k^2+V^2=R^2)

uwaga! R2 musi być większe lub równe V2 inaczej brak rozwiązania

obracamy wektor V o 90 stopni
W = (Vy, -Vx)

możliwe środki okręgu
O1 = S + k * W/|W|
O2 = S - k * W/|W|

można rozwinąć, za |W| podstawić sqrt(V^2), trochę się uprości
O1 = S + k * W / |W| = S + sqrt(R^2-V^2) * W / sqrt(V^2)

O1 = S + sqrt(R^2 / V^2 - 1) * W
O2 = S - sqrt(R^2 / V^2 - 1) * W

(R2 / V2 - 1) musi wyjść większe lub równe 0, inaczej brak rozwiązania

0

jakby dla potomnych kogoś interesowało rozwiązanie:

void calculate(double x1, double y1, double x2, double y2, double r, double *p1, double *r1, double *p2, double *r2)
{
    double x_s, y_s;
    x_s = (x1+x2)/2;
    y_s = (y1+y2)/2;

    double a, b;
    a = (y1-y2)/(x1-x2);
    b = y1 - a * x1;

    double a1, b1;
    a1 = -1/a;
    b1 = y_s - a1*x_s;

    double aa, bb, cc;
    aa = 1+ a1*a1;
    bb = -(2*x1 + 2*a1*(y1-b1));
    cc = x1*x1 + (y1-b1)*(y1-b1) - r*r;

    double delta;
    delta = bb*bb - 4 * aa * cc;

    *p1 = ((-bb) + sqrt(delta))/ (2*aa);
    *p2 = ((-bb) - sqrt(delta))/ (2*aa);

    *r1 = a1 * *p1 + b1;
    *r2 = a1 * *p2 + b1;
}
0

Zadanie na poziomie matury podstawowej z matematyki, przynajmniej taką mam nadzieję. Choć patrząc na to, jak się obniża wymagania wobec licealistów, nie dziwię się, że ich umiejętności są takie, jakie są.

0

Dość okrężne to rozwiązanie. Idąc za radą której udzieliłem wcześniej można dojść do takiego kodu:

bool calculate(double x1, double y1, double x2, double y2, double r, double *p1, double *r1, double *p2, double *r2)
{
    double vx = (x2 - x1) / 2;
    double vy = (y2 - y1) / 2;

    double dist = sqrt((r * r) / (vx * vx + vy * vy) - 1);

    *p1 = x1 + vx + dist * vy;
    *p2 = x1 + vx - dist * vy;
    *r1 = y1 + vy - dist * vx;
    *r2 = y1 + vy + dist * vx;
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1