WaBis

walter.bislins.ch

Schnittpunkte zweier Kreise berechnen (JavaScript)

Sonntag, 18. Januar 2015 - 02:24 | Autor: wabis | Themen: Wissen, Geometrie, Programmierung, Animation, Interaktiv | Kommentare(8)
Wie lassen sich die Schnittpunkte zweier Kreise berechnen, welche durch die Koordinaten der beiden Kreiszentren und deren beider Radien gegeben sind?

Ich zeige, wie durch Definieren eines speziellen Koordinatensystems sich die Aufgabe wesentlich vereinfachen lässt. Ich leite die Gleichungen her und erstelle ein JavaScript, welches die Schnittpunkte zweier beliebiger Kreise berechnet. Eine interaktive Animation zeigt das JavaScript in Aktion.

Aufgabe

Gegeben seien die zwei Kreise A und B. Von jedem Kreis kenne ich die Zentren \vec A und \vec B in Vektorform und die Radien a und b. Gesucht sind die Schnittpunkte der beiden Kreise \vec Q_1 und \vec Q_2 ebenfalls in Vektorform.

Zum Rechenformular

Vereinfachnung der Aufgabe

Wenn ich das Koordinatensystem ins Zentrum von Kreis A lege und die X-Achse durch das Zentrum von Kreis B lege, ergibt sich ein symmetrisches System bezüglich der X-Achse. Dadurch erhalte ich besonders einfache Formeln für Kreise. So lässt sich die Aufgabe leicht lösen. Danach kann ich die Lösung wieder in die Vektorform bringen.

Schnittbild zweier Kreise 
(Klick: Zoom)

In der Grafik bilden der Abschnitt x und y zusammen mit dem Radius a ein rechtwinkliges Dreieck. Für dieses gilt nach Pythagoras die Formel (1).

c sei die Strecke auf der X-Achse von A bis B. Dann bildet der Abschnitt cx und y mit dem Radius b ebenfalls ein rechtwinkliges Dreieck, für welches die Formel (2) gilt:

(1)
x^2 + y^2 = a^2
(2)
(c - x)^2 + y^2 = b^2
wobei'
a ' =' 'Radius von Kreis A
b ' =' 'Radius von Kreis B
c ' =' 'Abstand der Kreiszentren
x ' =' 'X-Abstand der beiden Schnittpunkte vom Ursprung
y ' =' 'Y-Abstand der beiden Schnittpunkte von der X-Achse

Der Abstand der beiden Kreise c berechnet sich wiefolgt aus den beiden Kreiszentren A und B:

(3)
c = | \vec B - \vec A | = \sqrt{ (B_\mathrm{x} - A_\mathrm{x})^2 + (B_\mathrm{y} - A_\mathrm{y})^2 }

Wir haben nun zwei Gleichungen (1) und (2) für die beiden Unbekannten x und y. Diese gilt es nun zu berechnen. Dazu löse ich (1) nach y2 auf:

(4)
y^2 = a^2 - x^2

und ersetze in (2) y2 durch den rechten Teil von (4):

(5)
(c - x)^2 + (a^2 - x^2) = b^2

Ausmultiplizieren ergibt:

(6)
c^2 \color{red}{+ x^2} - 2cx + a^2 \color{red}{- x^2} - b^2 = 0

Die x2 heben sich auf. Es kommt nur noch x ohne Potenz vor. Ich kann somit nach x auflösen:

(7)
x = { a^2 + c^2 - b^2 \over 2 c }

Beachte, dass x nur definiert ist, wenn c0 ist. Ist c = 0, dann sind die beiden Kreiszentren identisch. Wenn die beiden Radien ebenfalls identisch sind, ist der ganze Kreisumfang der beiden Kreise eine Lösung. Sind die Radien verschieden, gibt es keinen Schnittpunkt.

Wenn c0 ist, kann ich y mit der Formel (4) berechnen und erhalte die zwei Lösungen:

(8)
y_{1,2} = \pm \sqrt{ a^2 - x^2 }

Beachte, dass es nur eine Lösung gibt, wenn der Ausdruck unter der Wurzel positiv ist, also wenn a2x2 ist. Ist dies nicht der Fall, sind die Kreise zu weit voneinander weg und schneiden sich deshalb nicht. Ist der Ausdruck unter der Wurzel gerade 0, dann berühren sich die beiden Kreise in einem Punkt.

Lösung in Vektorform

Um die obigen Lösungen x und y1,2 wieder ins ursprüngliche Korrdinatensystem der Kreise zu transformieren, brauche ich die Einheitsvektoren \vec e_1 und \vec e_2 des Hilfskoordinatensystems bezüglich des originalen Koordinatensystem. Durch Vektor-Addition kann ich damit die obigen Lösungen ins originale Koordinatensystem transformieren.

Der Einheitsvektor der X-Achse \vec e_1 zeigt vom Kreiszentrum A zum Kreiszentrum B. Einen Vektor, der in diese Richtung zeigt, erhalte ich mit \vec {AB} = \vec B - \vec A. Wenn ich den Vektor \vec {AB} durch seine Länge | \vec {AB} | = | \vec B - \vec A | = c teile, bekomme ich den gewünschten Einheitsvektor \vec e_1:

(9)
\vec e_1 = \pmatrix{ e_{1,\mathrm{x}} \\ e_{1,\mathrm{y}} } = { \vec B - \vec A \over | \vec B - \vec A | } = { 1 \over c } \, \pmatrix{ B_\mathrm{x} - A_\mathrm{x} \\ B_\mathrm{y} - A_\mathrm{y} } \qquad \Rightarrow
(10)
e_{ 1,\mathrm{x} } = { B_\mathrm{x} - A_\mathrm{x} \over c } \qquad \text{ und } \qquad e_{ 1,\mathrm{y} } = { B_\mathrm{y} - A_\mathrm{y} \over c }

Den Einheitsvektor in Y-Richtung \vec e_2 erhalte ich durch rotieren von \vec e_1 um 90 Grad nach links. Dies ist eine einfache Matrix-Operation. Ich schreibe einfach mal das Resultat hin:

(11)
\vec e_2 = \pmatrix{ e_{2,\mathrm{x}} \\ e_{2,\mathrm{y}} } = \pmatrix{ -e_{1,\mathrm{y}} \\ e_{1,\mathrm{x}} } \qquad \Rightarrow
(12)
e_{ 2,\mathrm{x} } = -e_{ 1,\mathrm{y} } = -{ B_\mathrm{y} - A_\mathrm{y} \over c } \qquad \text{ und } \qquad e_{ 2,\mathrm{y} } = e_{ 1,\mathrm{x} } = { B_\mathrm{x} - A_\mathrm{x} \over c }

Die Schnittpunkte Q1 und Q2 erhalte ich, indem ich von \vec A aus x Einheiten in Richtung \vec e_1 gehe und dann ± y Einheiten in Richtung \vec e_2:

(13)
\vec Q_{1,2} = \vec A + x \cdot \vec e_1 \pm y \cdot \vec e_2

oder in Komponenten ausgeschrieben:

(14)
Q_{ 1,\mathrm{x} } = A_\mathrm{x} + x \cdot { B_\mathrm{x} - A_\mathrm{x} \over c } - y \cdot { B_\mathrm{y} - A_\mathrm{y} \over c } \qquad \text{ und } \qquad Q_{ 1,\mathrm{y} } = A_\mathrm{y} + x \cdot { B_\mathrm{y} - A_\mathrm{y} \over c } + y \cdot { B_\mathrm{x} - A_\mathrm{x} \over c }
und
Q_{ 2,\mathrm{x} } = A_\mathrm{x} + x \cdot { B_\mathrm{x} - A_\mathrm{x} \over c } + y \cdot { B_\mathrm{y} - A_\mathrm{y} \over c } \qquad \text{ und } \qquad Q_{ 2,\mathrm{y} } = A_\mathrm{y} + x \cdot { B_\mathrm{y} - A_\mathrm{y} \over c } - y \cdot { B_\mathrm{x} - A_\mathrm{x} \over c }

Der Schnittpunkt Q1 liegt damit immer links von der Achse AB.

Zusammenfassung

Hier nochmals alle benötigten Formeln in der Reihenfolge der Berechnung, zusammengefasst an einer Stelle:

(15)
c = \sqrt{ (B_\mathrm{x} - A_\mathrm{x})^2 + (B_\mathrm{y} - A_\mathrm{y})^2 }

Wenn c = 0 ist, sind die Kreiszentren identisch, d.h. es gibt keine Lösung, wenn ab ist. Wenn a = b ist sind die Kreise identisch, d.h. der Kreis selbst ist die Lösungsmenge. Wenn c > 0 ist, können wir weiterrechnen:

(16)
x = { a^2 + c^2 - b^2 \over 2 \, c }

Wenn x2 > a2 ist, wird der Ausdruck unter der Wurzel in der nächsten Formel negativ. Das Bedeutet dann, dass die beiden Kreise keinen Schnittpunkt haben. Es gibt dann keine Lösung. Wenn x2 = a2 ist, wird y = 0. In diesem Fall gibt es nur einen Schnittpunkt, an dem sich die beiden Kreise berühren. Es reicht in dem Fall, Q1 zu berechnen, denn wenn wir y = 0 in die nachfolgenden Formeln einsetzen erhalten wir für beide Punkte die selben Formeln:

(17)
y = \sqrt{ a^2 - x^2 }

Nun können wir die beiden Schnittpunte nach folgenden Formeln berechnen:

(18)
Q_{ 1,\mathrm{x} } = A_\mathrm{x} + x \cdot { B_\mathrm{x} - A_\mathrm{x} \over c } - y \cdot { B_\mathrm{y} - A_\mathrm{y} \over c } \qquad \text{ und } \qquad Q_{ 1,\mathrm{y} } = A_\mathrm{y} + x \cdot { B_\mathrm{y} - A_\mathrm{y} \over c } + y \cdot { B_\mathrm{x} - A_\mathrm{x} \over c }
und
Q_{ 2,\mathrm{x} } = A_\mathrm{x} + x \cdot { B_\mathrm{x} - A_\mathrm{x} \over c } + y \cdot { B_\mathrm{y} - A_\mathrm{y} \over c } \qquad \text{ und } \qquad Q_{ 2,\mathrm{y} } = A_\mathrm{y} + x \cdot { B_\mathrm{y} - A_\mathrm{y} \over c } - y \cdot { B_\mathrm{x} - A_\mathrm{x} \over c }

JavaScript Intersect2Circles

Vektoren sind 2-dimensionale Arrays mit den X- und Y-Koordinaten der Punkte. Das JavaScript gibt als Lösung einen Array mit den zwei Vektoren \vec Q_1 und \vec Q_2 zurück. Wenn es nur einen Schnittpunkt gibt, wird nur ein Schnittpunkt im Array zurückgegeben. Wenn sich die Kreise nicht schneiden oder wenn die beiden Kreise dasselbe Zentrum haben, wird ein leeres Array zurückgegeben.

function Intersect2Circles( A, a, B, b ) {
  // A, B = [ x, y ]
  // return = [ Q1, Q2 ] or [ Q ] or [] where Q = [ x, y ]
  var AB0 = B[0] - A[0];
  var AB1 = B[1] - A[1];
  var c = Math.sqrt( AB0 * AB0 + AB1 * AB1 );
  if (c == 0) {
    // no distance between centers
    return [];
  }
  var x = (a*a + c*c - b*b) / (2*c);
  var y = a*a - x*x;
  if (y < 0) {
    // no intersection
    return [];
  }
  if (y > 0) y = Math.sqrt( y );
  // compute unit vectors ex and ey
  var ex0 = AB0 / c;
  var ex1 = AB1 / c;
  var ey0 = -ex1;
  var ey1 =  ex0;
  var Q1x = A[0] + x * ex0;
  var Q1y = A[1] + x * ex1;
  if (y == 0) {
    // one touch point
    return [ [ Q1x, Q1y ] ];
  } 
  // two intersections
  var Q2x = Q1x - y * ey0;
  var Q2y = Q1y - y * ey1;
  Q1x += y * ey0;
  Q1y += y * ey1;
  return [ [ Q1x, Q1y ], [ Q2x, Q2y ] ];
}

Animation

Rechenformular

Mit Hilfe des Formulars kannst du die Schnittpunkte Q1 und Q2 zweier Kreise A und B berechnen. Zusätzlich werden die Zwischenresultate c, x und y der obigen Formeln angezeigt.

Kommentare

1Steffen0815 23.06.2015 | 00:17

Kann mir hier mal jemand helfen, ich Blick gar nicht durch. Hab zwei Kreise, Kreis 1: R=20,205 mm und Kreis 2: R=14,4 mm. Kreis 1: R 20,205 hat die Mittelpunkte x=0 und y=0 ; Kreis 2: R 14,4 x=13,35 y=0

Wollt die genauen Formeln die ich in den Taschenrechner tippen muss :(

2wabiswalter@bislins.ch (Walter Bislin, Autor dieser Seite) 24.06.2015 | 01:21

@Steffen

Im allgemeinen Fall kann man keine einfache Formel für die Schnittpunkte zweier Kreise angeben. Die Berechnung muss in mehrere Schritte aufgeteilt werden. Je nach Zwischenresultat eines dieser Schritte kann man nicht weiter rechnen, weil in diesen Fällen gar keine Schnittpunkte existieren (Kreise sind zu weit voneinander entfernt, oder ein Kreis liegt vollständig innerhalb des anderen, oder beide Kreise haben das gleiche Zentrum).

In deinem Fall, wo der erste Kreis Ax = Ay = 0 und der Zweite Kreis By = 0 hat, können die allgemeinen Formeln stark vereinfacht werden, eben weil viele Werte Null sind und man daher nicht mit Vektoren weiterrechnen muss. In diesem Fall sehen die Formeln wiefolgt aus, wobei c durch Bx ersetzt werden kann:

x = { a^2 + {B_\mathrm{x}}^2 - b^2 \over 2 \cdot B_\mathrm{x} }

Wenn x2 nun grösser als Radius a2 des Kreises A ist, gibt es keine Schnittpunkte (der Wert unter der Wurzel unten wäre dann negativ). Ansonsten können wir weiterrechnen:

y = \sqrt{ a^2 - x^2 }

Und damit wären dann die Schnittpunkte:

Q_{1,\mathrm{x}} = x \qquad Q_{1,\mathrm{y}} = y
Q_{2,\mathrm{x}} = x \qquad Q_{2,\mathrm{y}} = -y

Für alle weiteren Fälle kannst du neu das obige Rechenformular verwenden.

3Johannes 14.04.2016 | 15:42

Hallo,
ich komme bei einer Aufgabenstellung nicht weiter. Zu bestimmen sind die Schnittpunkte zweier Kreise, dabei bewegt sich der kleinere Kreis auf der Tangente des anderen. Es muss also eine Funktion aufgestellt werden, die die Schnittpunkte in Abhängigkeit zur Position des Zentrums des kleinen Kreises auf der Tangente beschreibt.
Vielleicht kann mir jemand helfen.
Danke

4wabiswalter@bislins.ch (Walter Bislin, Autor dieser Seite) 18.04.2016 | 18:27

@Joahnnes

Ich bin mir nicht sicher, ob ich die Aufgabe richtig verstanden habe. Wenn das Zentrum des einen Kreises, sagen wir Kreis A, auf der Tangente des anderen Kreises B liegen soll und das Ganze ohne konkrete Zahlenwerte, also als Formeln ausgedrückt werden soll, muss zuerst eine Gleichung für die Tangente aufgestellt werden.

Eine Tangente ist eine Gerade, die in folgender Form als Vektor-Gleichung geschrieben werden kann:

(19)
\vec P(\lambda) = \vec T + \lambda \, \vec t
wobei'
\vec P(\lambda) ' =' 'Punkt auf der Tangente an der Stelle \lambda
\vec T ' =' 'Berührungspunkt der Tangente mit dem Kreis
\vec t ' =' 'Vektor, der die Richtung der Tangente angibt
\lambda ' =' 'Ein Parameter

In Komponenten ausgeschrieben:

(20)
P_\mathrm{x}(\lambda) = T_\mathrm{x} + \lambda \, t_\mathrm{x}
und
P_\mathrm{y}(\lambda) = T_\mathrm{y} + \lambda \, t_\mathrm{y}

Der Berührungspunkt T liegt auf dem Kreis B. Ein solcher Punkt kann in Abhängigkeit eines Winkels \alpha angegeben werden:

(21)
T_\mathrm{x} = B_\mathrm{x} + b \, \cos( \alpha )
und
T_\mathrm{y} = B_\mathrm{y} + b \, \sin( \alpha )
wobei'
T_\mathrm{x}, T_\mathrm{y} ' =' 'Berührungspunkt der Tangente mit dem Kreis B
B_\mathrm{x}, B_\mathrm{y} ' =' 'Kreiszentrum des Kreises B
b ' =' 'Radius des Kreises B
\alpha ' =' 'Winkel zwischen der Strecke von B nach T und der X-Achse

Der Tangentenvektor \vec t ist natürlich auch vom Berührungspunkt abhängig. Er bildet zur Strecke BT einen rechten Winkel und kann wiefolgt berechnet werden:

(22)
t_\mathrm{x} = \sin( \alpha)
und
t_\mathrm{y} = - \cos( \alpha )

Damit wird die allgemeine Tangentengleichung für eine beliebige Tangente an den Kreis B:

(23)
P_\mathrm{x}( \lambda ) = B_\mathrm{x} + b \, \cos( \alpha ) + \lambda \, \sin( \alpha )
und
P_\mathrm{y}( \lambda ) = B_\mathrm{y} + b \, \sin( \alpha ) - \lambda \, \cos( \alpha )

Der Punkt P liegt immer auf der Tangente an den Kreis B. Der Punkt P soll laut Aufgabe das Zentrum des Kreises A sein. Wir müssen daher in allen Kreisgleichungen unter Zusammenfassung Ax = Px und Ay = Py setzen. Dann erhalten wir allgemeine Formeln für die Schnittpunkte der Kreise in Abhängikeit des Paramters \lambda und des Winkels \alpha.

Beachte: das Ganze in eine einzige Formel zu packen ist viel zu unübersichtlich!

5FAN 18.07.2016 | 18:12

Hey wabis,

danke für die schöne Aufbereitung und gute Erklärung!

6Karl 27.07.2016 | 13:48

Eine sehr transparente und präzise Darstellung - vielen Dank für Arbeit!

7Andi 27.04.2017 | 11:55

Gibt es auch eine Möglichkeit die Schnittfläche zu bestimmen?

Ich stehe vor dem Problem, dass ich zwei Mengen sowie die gemeinsame Schnittmenge grafisch darstellen möchte. Jetzt weiß ich aber leider nicht wie weit die Kreise auseinander sein müssen damit die korrekte Schnittfläche grafisch dargestellt wird.

LG, Andi

8wabiswalter@bislins.ch (Walter Bislin, Autor dieser Seite) 04.05.2017 | 00:33

Hallo Andi

Ich habe eine Seite erstellt, wo Du das alles nachlesen kannst. Es gibt auch ein Rechenformular dazu.

 Schnittfläche zweier Kreise berechnen

Dein Kommentar zu diesem Artikel
Name
Email optional; wird nicht angezeigt
Kommentar
  • Name wird bei deinem Kommentar angezeigt.
  • Email ist nur für den Administrator, sie wird nicht angezeigt.
  • Du kannst deine Kommentare eine Zeit lang editieren oder löschen.
  • Du kannst Formatierungen im Kommentar verwenden, z.B: Code, Formeln, usw.
  • Externen Links und Bilder werden nicht angezeigt, bis sie der Admin freischaltet.
Weitere Infos zur Seite
Erzeugt Samstag, 17. Januar 2015
von wabis
Zum Seitenanfang
Geändert Donnerstag, 4. Mai 2017
von wabis