Programowanie w języku C/C++ » Artykuły

Współrzędne środka okręgu przechodzącego przez trzy punkty

  • 2009-01-17 09:26
  • 6 komentarzy
  • 3549 odsłon
  • Oceń ten tekst jako pierwszy
Ktoś kiedyś powiedział, że przez trzy punkty spełniające pewne założenia można poprowadzić tylko okrąg o ściśle określonym promieniu. W artykule tym pragnę przedstawić wzór na znajdowanie środka okręgu przechodzącego przez trzy punkty "p1", "p2" oraz "p3", które spełniają następujące założenia:

p1 != p2 && p2 != p3 && p1 != p3
oraz
wszystkie trzy punkty nie mogą leżeć na tej samej linii

Jeżeli chodzi o sam wzór, to wyprowadza się go ze wzoru, który z pewnością wszyscy znacie z lekcji matematyki:

{R<sup>2=(X-X_s)</sup>2+(Y-Y_s)^2}

a więc istnieje możliwość zapisania trzech równań:

{R<sup>2=(p1.x-X_s)</sup>2+(p1.y-Y_s)^2}

{R<sup>2=(p2.x-X_s)</sup>2+(p2.y-Y_s)^2}

{R<sup>2=(p3.x-X_s)</sup>2+(p3.y-Y_s)^2}

promień okręgu nie jest nam znany więc z trzech równań trzeba zrobić dwa:

{(p3.x-X_s)<sup>2+(p3.y-Y_s)</sup>2=(p1.x-X_s)<sup>2+(p1.y-Y_s)</sup>2}

{(p3.x-X_s)<sup>2+(p3.y-Y_s)</sup>2=(p2.x-X_s)<sup>2+(p2.y-Y_s)</sup>2}

powyższy układ równań nie należy do najprostszych w rozwiązaniu a wpisywanie wzorów na tym forum jest nieco uciążliwe, więc od razu przejdę do ostatecznego wzoru:

X_s = \frac{1}{2}\cdot\frac{p2.x<sup>2\cdot p3.y+p2.y</sup>2\cdot p3.y-p1.x<sup>2\cdot p3.y+p1.x</sup>2\cdot p2.y-p1.y<sup>2\cdot p3.y+p1.y</sup>2\cdot p2.y+p1.y\cdot p3.x<sup>2+p1.y\cdot p3.y</sup>2-p1.y\cdot p2.x^2}{p1.y\cdot p3.x-p1.y\cdot p1.x-p2.y\cdot p3.x-p3.y\cdot p1.x+p3.y\cdot p2.x+p2.y\cdot p2.x}+

 \frac{1}{2}\cdot\frac{-p1.y\cdot p2.y\cdot p2.y-p2.y\cdot p3.x<sup>2-p2.y\cdot p3.y</sup>2}{p1.y\cdot p3.x-p1.y\cdot p1.x-p2.y\cdot p3.x-p3.y\cdot p1.x+p3.y\cdot p2.x+p2.y\cdot p2.x}

w TeX-sie niestety musiałem rozbić cały ułamek na dwie części, bo nie mieścił się na stronie.

Na wszelki wypadek i dla świętego spokoju zostawiam starą wersję zapisu (bez TeX-a)

        1     (p2.x * p2.x * p3.y + p2.y * p2.y * p3.y - p1.x * p1.x * p3.y + p1.x * p1.x * p2.y - p1.y * p1.y *
Xs = -- * -----------------------------------------------------------------------------------------------------------------
        2    

p3.y + p1.y * p1.y * p2.y + p1.y * p3.x * p3.x + p1.y * p3.y * p3.y - p1.y * p2.x * p2.x - p1.y * p2.y *


 p1.y * p3.x - p1.y * p1.x - p2.y2 * p3.x - p3.y * p1.x + p3.y * p2.x + p2.y * p2.x

p2.y - p2.y * p3.x * p3.x - p2.y * p3.y * p3.y)


 

No dobra Xs jest już z głowy, teraz Ys:

Y_s=\frac{1}{2}\cdot\frac{-p1.x\cdot p3.x<sup>2-p1.x\cdot p3.y</sup>2+p1.x\cdot p2.x<sup>2+p1.x\cdot p2.y</sup>2+p2.x\cdot p3.x<sup>2+p2.x\cdot p3.y</sup>2-p2.x<sup>2\cdot p3.x-p2.y</sup>2\cdot p3.x+p1.x^2\cdot p3.x}{p1.y \cdot p3.x - p1.y \cdot p2.x - p2.y \cdot p3.x - p3.y \cdot p1.x + p3.y \cdot p2.x + p2.y \cdot p1.x}+

 \frac{1}{2}\cdot\frac{- p1.x<sup>2\cdot p2.x + p1.y</sup>2\cdot p3.x - p1.y^2\cdot p2.x}{p1.y \cdot p3.x - p1.y \cdot p2.x - p2.y \cdot p3.x - p3.y \cdot p1.x + p3.y \cdot p2.x + p2.y \cdot p1.x}

        1     (-p1.x * p3.x * p3.x - p1.x * p3.y * p3.y + p1.x * p2.x * p2.x + p1.x *  p2.y * p2.y + p2.x *
Ys = -- * ----------------------------------------------------------------------------------------------------------------
        2

p3.x * p3.x + p2.x * p3.y * p3.y - p2.x * p2.x * p3.x - p2.y * p2.y * p3.x + p1.x * p1.x * p3.x - p1.x *


p1.y * p3.x - p1.y * p2.x - p2.y * p3.x - p3.y * p1.x + p3.y * p2.x + p2.y * p1.x

p1.x * p2.x + p1.y * p1.y * p3.x - p1.y * p1.y * p2.x


 

No i to by było na tyle, może jeszcze tylko dodam jak obliczyć promień (co jest banalne). Jeżeli czytaliście artykuł Operacje_na_wektorach to wiecie jak stworzyć klasę opisującą wektor i jak obsłużyć podstawowe operatory dla tej klasy i metody. Używając takiej klasy można obliczyć promień w następujący sposób:

ray = (P1 - Ps).Length();

gdzie Length jest metodą zwracającą długość wektora uzyskanego z różnicy wektorów P1 - Ps.

A oto przykład gotowej funkcji


void CircleCenter(double x1,double y1,double x2,double y2,double x3,double y3,double &Xs,double &Ys){
        Xs = 0.5 * (x2 * x2 * y3 + y2 * y2 * y3 - x1 * x1 * y3 + x1 * x1 * y2 - y1 * y1 * y3 + y1 * y1 * y2 + y1 * x3 * x3 + y1 * y3 * y3 - y1 * x2 * x2 - y1 * y2 * y2 - y2 * x3 * x3 - y2 * y3 * y3) / (y1 * x3 - y1 * x2 - y2 * x3 - y3 * x1 + y3 * x2 + y2 * x1);
        Ys = 0.5 * (-x1 * x3 * x3 - x1 * y3 * y3 + x1 * x2 * x2 + x1 * y2 * y2 + x2 * x3 * x3 + x2 * y3 * y3 - x2 * x2 * x3 - y2 * y2 * x3 + x1 * x1 * x3 - x1 * x1 * x2 + y1 * y1 * x3 - y1 * y1 * x2) / (y1 * x3 - y1 * x2 - y2 * x3 - y3 * x1 + y3 * x2 + y2 * x1));
}


Tutaj możesz pobrać program rysujący koło przechodzące przez trzy punkty z kodem źródłowym

6 komentarzy

Coldpeer 2009-01-17 23:57

Koziołek: raczej to miało być do gringoM, który jest autorem tego arta ;)

Koziołek 2008-10-29 13:38

Coldpeer nie zgodzę się że punkty leżące na jednej prostej nie będą się nadawały. Wynikiem będzie nieskończoność.

Artykuł świetny swoją drogą coraz bardziej podoba mi się Coyote ma tyle fajnych featuerów np. interpretator Tex.

gringoM 2008-10-23 20:22

Coldpeer - dzięki wielkie za linka, bardzo dobrze opisane wszystko więc polecam go wszystkim tym, którzy potrzebują użyć wzoru w tekście.

Coldpeer 2008-10-21 17:37

Znalazłem takie coś - http://matematyka.pl/viewtopic.php?t=28951

//btw, teraz można użyć <tex>formułka</tex>

gringoM 2008-10-21 09:45

Użyłem TeX-a do wstawiania wzorów, niestety dwa ostatnie nie chciały się (przynajmniej na podględzie)  zamieniać na obraz więc zostawiłem jak jest.

P.S. jak w linku wpisuję to wszystko jest cacy tylko w artykule nie chce wstawić obrazu, pewnie wzór jest za długi i musiałbym go pociąć na kawałki.

Coldpeer - jeżeli masz linka do opisu tego wielce przydatnego narzędzia, to prosiłbym o jego podanie (nie żebym sam nie umiał niczego znaleźć, ale najlepiej zawsze szukać u źrudła)

Coldpeer 2008-10-21 00:03

btw, mamy TeX-a na serwerze - http://4programmers.net/cgi-bin/mimetex.cgi

Przykład:                                                                              (%5c to \)

<image>http://4programmers.net/cgi-bin/mimetex.cgi?%5cfrac{ax^2+bx+c}{x-a_2}</image>

<image>http://4programmers.net/cgi-bin/mimetex.cgi?%5cfrac{ax^2+bx+c}{x-a_2}</image>