Die Kreisabschnitte AA gelb und BA blau im Bild rechts können mit denselben Formeln separat berechnet werden. Dazu definieren wir einige Parameter wie im Bild unten beschriftet. Dies sind die Radien der beiden Kreise a und b, sowie deren Abstand d.
Im Bild unten sind zur besseren Übersicht jeweils nur die halben Flächen bezeichnet, in den Formeln wird aber mit den ganzen Flächen gerechnet. Die gesuchten Kreisabschnitte AA und BA berechnet man aus den Kreissektoren AS bzw. BS abzüglich der Dreiecke AD bzw. BD. Die gesuchte Schnittfläche S ist dann einfach die Summe der Kreisabschnitte.
Es müssen die drei folgenden Fälle unterschieden werden:
Für die Berechnungen der Kreisabschnitte müssen eventuell zwei weitere Fälle unterschieden werden: links der Fall bei dem alle Winkel des Dreiecks a-b-d kleiner als 90° sind, rechts der Fall, bei dem einer der Winkel grösser als 90° ist.
Für die Berechnung der Flächen führen wir den Abschnitt x sowie die Dreieckshöhe h ein. Der Abschnitt y ist entspricht dem Abschnitt x für den Kreis B, es ist also y = d − x. Für die Parameter gelten die folgenden Beziehungen nach Pythagoras:
(1) |
Wir können h eliminieren, indem wir die beiden Gleichungen einander gleich setzen, und nach x auflösen:
(2) |
Der Term −x2 kommt auf beiden Seiten vor und kann daher auf beiden Seiten gestrichen werden. Dann können wir nach x auflösen, das nur noch mit der ersten Potenz vorkommt.
Im Folgenden werden die Formeln für die beiden Kreise einander gegenüber gestellt. Der Abschnitt x für den linken Kreis entspricht dem Abschnitt y für den rechten Kreis. Alle Flächen des linken Kreises sind mit A bezeichnet, jene des rechten Kreises mit B.
(3) | |
mit |
|
(4) | |
mit |
|
Beachte, dass die Werte x bzw. y negativ sein können. Dies müssen wir berücksichtigen, wenn wir die Fläche der Sektoren AS und BS berechnen.
Zur Berechnung der Sektorflächen AS und BS benötigen wir die Sektorwinkel. Diese können wir im Prinzip aus dem arcsin oder dem arccos erhalten. Der arcsin ist hier nicht geeignet, weil er für negative x und y nicht den gewünschten Winkel zwischen π/2 und π liefert. Daher verwenden wir die arccos Funktion:
(5) | ||||||||||
ergibt |
| |||||||||
wobei' |
|
(6) | ||||||||||
ergibt |
| |||||||||
wobei' |
|
Beachte, dass die hier berechnete Fläche AS das doppelte der gelb gezeichneten Fläche im obigen Bild ist, da die Segmentfläche eines Kreises A = (α/2π) · r2 · π = α/2 · r2 ist. Dies gilt auch für die folgenden Berechnungen.
Um die Kreisabschnitte (Kreissegmente) AA und BA zu berechnen, benötigen wir die Flächen der Dreiecke AD und BD. Die Kreisabschnitte erhält man, indem man von den Kreissektoren die Flächen der Dreiecke abzieht, siehe (9) und (10).
Bei negativen x bzw. y wird der entsprechende Sektorwinkel grösser als π und wir müssen die Dreiecksflächen zu den Sektorflächen hinzufügen. In den folgenden Formeln erhalten wir negative Dreiecksflächen für Sektorwinkel grösser als π, sodass diese Fälle in (9) und (10) automatisch korrekt behandelt werden. Wir brauchen also keine extra Fallunterscheidung dafür zu machen.
(7) | ||||||||||
mit |
| |||||||||
ergibt |
| |||||||||
wobei' |
|
(8) | ||||||||||
mit |
| |||||||||
ergibt |
| |||||||||
wobei' |
|
Die Kreisabschnitts-Flächen sind:
Und schliesslich erhalten wir die Schnittfläche S der zwei Kreise:
(11) | ||||||||||
wobei' |
|
Wenn wir die Schnittfläche der zwei Kreise kennen, können wir den Abstand der Kreise berechnen. Im Prinzip müsste man dazu einfach die Formel (11) nach Einsetzen aller Zwischenformeln nach d auflösen. Da aber d sowohl im arccos, unter der Wurzel und separat steht, kann die Formel nicht analytisch nach d aufgelöst werden. Wir müssen ein numerisches Verfahren wie das Newton-Verfahren anwenden.
Beim Newton-Verfahren muss man einen sinnvollen Startwert vorgeben. Zudem sollte man die Funktion, deren Nullstelle man sucht, grafisch aufzeichnen, um zu sehen, ob es eine eindeutige Lösung gibt und wo ein geeigneter Startwert angesetzt werden muss, damit das Verfahren immer eine Lösung findet.
Ich generiere deshalb eine Grafik für verschiedene Radien und Abstände, um das Verhalten der Funktion zu analysieren:
In der Grafik ist die Schnittfläche S als Funktion des Abstandes der Kreise d für verschiedene Kombinationen von Kreisradien a und b aufgezeichnet. Wenn man nun zum Beispiel den Abstand d wissen will, bei dem die Schnittfläche 1 ist (rote Linie), so sucht man jene blaue Linie, die den beiden Radien der Kreise entspricht und sucht deren Schnittpunkt mit der roten Linie. Unterhalb des Schnittpunktes kann man den Abstand d ablesen.
Für das Newton-Verfahren ist wichtig, dass die blauen Kurven erstens die rote Linie überhaupt schneiden. Dies gilt nicht für alle Radien, aber die entsprechenden Fälle kann man aussortieren. Zweitens kann man sehen, dass es für jede blaue Linie nur genau einen Schnittpunkt mit der roten Linie gibt. D.h. es gibt immer eine eindeutige Lösung.
Die blauen Linien schneiden die rote Linie meist in einem steilen Winkel und die blauen Linien sind in einem grossen Bereich praktisch gerade. Das sind ideale Voraussetzungen für das Newton-Verfahren. Problematisch werden die Grenzfälle, wo die blauen Linien horizontal in die Horizontale über gehen. In diesen Fällen ist das Newton-Verfahren überfordert, da es bei horizontalen Lininen nicht gut oder überhaupt nicht konvergiert. Dies kann ich korrigieren, indem ich an die Enden je eine Parabel anhänge, welche die Funktion so erweitert, dass sie kontinuierlich abfallend wird. Damit kann das Verfahren zwar Werte ein wenig ausserhalb des Wertebereiches liefern, aber diese können in den Wertebereich zurück gespiegelt werden.
Als Startwert für das Newton-Verfahren kann d = (a+b)/2 gesetzt werden.
Um die Schnittfläche der beiden Kreise zu berechnen, gib a, b und den Abstand d ein. Die resultierende Schnittfläche wird im Feld S angezeigt.
Um den benötigten Abstand der beiden Kreise für eine vorgegebene Schnittfläche zu berechnen, gib in das Feld S die Schnittfläche ein. Der zugehörige Abstand wird im Feld d angezeigt.
#INCLUDE JsGraph.inc #INCLUDE ControlPanel.inc #INCLUDE NewtonSolver.inc {{col|50}} <jscript> function Area( a, b, d ) { // Schnittfläche berechnen var x = (a*a - b*b + d*d) / (2*d); var As = a*a * Math.acos( x / a ); var Ad = x * Math.sqrt( a*a - x*x ); var Aa = As - Ad; var y = (b*b - a*a + d*d) / (2*d); var Bs = b*b * Math.acos( y / b ); var Bd = y * Math.sqrt( b*b - y*y ); var Ba = Bs - Bd; return Aa + Ba; } function S( a, b, d ) { // Test ob d ausserhalb des Bereiches liegt if (d >= a + b) return 0; if (d <= Math.abs(a-b)) { var r = (a > b) ? b : a; return r*r * Math.PI; } return Area( a, b, d ); } function Sx( a, b, d ) { // Funktion an den Enden des Wertebereiches d für das Newton-Verfahren erweitern mit Parabeln var dmax = a + b; if (d >= dmax) return -Math.pow(d-dmax, 2); var dmin = Math.abs(a-b); if (d <= dmin) { var r = (a > b) ? b : a; var Smin = r*r * Math.PI; return Math.pow(d-dmin,2) + Smin; } return Area( a, b, d ); } var Model = { a: 1, b: 1, d: 1.5, S: 0, S_field: 0, Update: function() { // ungültige Eingaben korrigieren if (isNaN(this.a)) this.a = 1; if (isNaN(this.b)) this.b = 1; if (isNaN(this.d)) this.d = 1.5; if (isNaN(this.S_field)) this.S_field = this.S; this.a = Math.abs(this.a); this.b = Math.abs(this.b); this.d = Math.abs(this.d); // test, ob S verändert wurde if (this.S != this.S_field) { this.S = Math.abs(this.S_field); this.d = this.ComputeD(); } else { this.S = S( this.a, this.b, this.d ); } this.S_field = this.S; }, ComputeD: function() { // wenn S ausserhalb des Wertebereiches liegt... if (this.S <= 0) return this.a + this.b; var r = (this.a > this.b) ? this.b : this.a; var smax = Math.PI * r * r; if (this.S >= smax) { this.S = smax; return 0; } // Abstand d mit Newton-Verfahren berechnen var me = this; var d = SolveWithNewton( function(x){ return Sx( me.a, me.b, x ); }, this.S, (this.a+this.b)/2, 1e-6 ); // wenn d ausserhalb des Wertebereiches 0..a+b liegt, dann // d in den Wertebereich zurück spiegeln if (d < 0) d = -d; if (d > this.a+this.b) d = 2 * (this.a+this.b) - d; return d; } } var ModelGraph = NewGraph2D( { Id: 'ModelGraph', Width: '100%', Height: '75%', DrawFunc: DrawModelGraph, AutoReset: true, AutoClear: true, AutoScalePix: true } ); function DrawModelGraph( g ) { // compute window size var abd = Model.a + Model.b + Model.d; if (Model.a + Model.d < Model.b) abd = 2 * Model.b; if (Model.b + Model.d < Model.a) abd = 2 * Model.a; var wModel = 1.05 * abd; var hModel = (Model.a > Model.b) ? Model.a : Model.b; hModel *= 2.1; if (wModel == 0 || hModel == 0) return; var vpRatio = g.VpInnerWidth / g.VpInnerHeight; var modelRatio = wModel / hModel; var WinWidth = wModel; var WinHeight = hModel; if (modelRatio > vpRatio) { WinHeight = wModel / vpRatio; } else { WinWidth = hModel * vpRatio; } var l = Model.a; if (Model.b - Model.d > Model.a) l = Model.b - Model.d; var WinXmin = -(WinWidth/2 - abd/2 + l); var WinYmin = -0.5 * WinHeight; g.SetWindowWH( WinXmin, WinYmin, WinWidth, WinHeight ); // draw circles g.SetAlpha( 0.5 ); g.SetAreaAttr( '#f88', 'black', 2 ); g.Circle( 0, 0, Model.a, 3 ); g.SetAreaAttr( '#88f', 'black', 2 ); g.Circle( Model.d, 0, Model.b, 3 ); g.SetAlpha( 1 ); g.Circle( 0, 0, Model.a, 1 ); g.Circle( Model.d, 0, Model.b, 1 ); // draw circle centers g.SetMarkerAttr( 'Plus', 12, 'black', 'black', 1 ); g.Marker( 0, 0 ); g.Marker( Model.d, 0 ); // draw a, b, d var rx = Math.sin(Math.PI/4); var ry = Math.cos(Math.PI/4); g.SetMarkerAttr( 'Arrow1', 10 ); g.SetAreaAttr( 'red', 'red', 2 ); g.Arrow( 0, 0, -Model.a*rx, Model.a*ry ); g.SetTextSize( 24 ); g.SetTextColor( 'red' ); g.SetTextAlign( 'left', 'bottom' ); g.SetTextPadding( 5 ); g.Text( 'a', -Model.a*rx/2, Model.a*ry/2 ); g.SetAreaAttr( 'blue', 'blue', 2 ); g.Arrow( Model.d, 0, Model.b*rx+Model.d, Model.b*ry ); g.SetTextColor( 'blue' ); g.SetTextAlign( 'right', 'bottom' ); g.Text( 'b', Model.d+Model.b*rx/2, Model.b*ry/2 ); g.SetLineAttr( 'black', 2 ); g.Line( 0, 0, Model.d, 0 ); g.SetTextAlign( 'center', 'bottom' ); g.SetTextColor( 'black' ); g.Text( 'd', Model.d/2, 0 ); } </jscript> {{col}} <jscript> ControlPanels.NewPanel( { ModelRef: 'Model', NCols: 2, PanelFormat: 'InputMaxWidth', OnModelChange: UpdateAll, Format: 'std', Digits: 6, } ).AddHeader( { ColSpan: 4, Text: ControlPanels.ResetButtonR(), } ).AddTextField( { Name: 'a' } ).AddTextField( { Name: 'b' } ).AddTextField( { Name: 'd', } ).AddTextField( { Name: 'S', ValueRef: 'S_field' } ).Render(); function UpdateAll() { Model.Update(); ControlPanels.Update(); ModelGraph.Redraw(); } function Reset() { ControlPanels.Reset(); Model.S = Model.S_field; UpdateAll(); } xOnLoad( UpdateAll ); </jscript>
Sehr gute detaillierte Herleitung,
schade, dass die Berechnung in C erfolgt. VBA in Excel wäre mir lieber.
LG
ws
Tippfehler
Am Ende des Satzes muss stehen "rechten" und nicht "rechnten"
Satz: Im Folgenden werden die Formeln für die beiden Kreise einander gegenüber gestellt. Der Abschnitt x für den linken Kreis entspricht dem Abschnitt y für den rechnten Kreis.
@Lothar, vielen Dank für die Aufmerksamkeit. Fehler ist korrigiert.
Hallo Walter,
ich bin auf deine Seite gestoßen, weil ich mich intensiv mit diesem Problem beschäftige, nämlich aus der vorgegebenen, beliebigen Schnittflächengröße (> 0% - < 100% der Kreisfläche) von zwei sich überlappenden Kreisen mit gleichem Radius, den Abstand d von M1 und M2 zu berechnen. Dein beeindruckender Lösungsweg ist, wenn ich es richtig sehe, ein iteratives Näherungsverfahren (Newton), also kein rein analytisches Berechnungsverfahrem. Mein Lösungsweg ist ein analytisches Berechnungsverfahren (Integralmethode) und wenn du Interesse hast, würde ich dir gerne meinen Lösungsweg per Email zukommen lassen.
Viele Grüße, Dieter
Ergänzung zu meiner Mail am 9.08.22:
für a = 1, b = 1, S = 1,5708 (pi/2)
d = 0,807943 (dein Rechnerergebnis)
d = 0,807946 (meine Berechnung nach der Integralmethode)
Hallo, gegeben ist ein Vierpass, also vier Kreise gleichen Radius’. Diese vier Kreise berühren sich am Schnittpunkt von x und y Achse. Von zwei Kreisen liegt der Mittelpunkt auf der x~Achse, sie tangieren die y-Achse, aber schneiden sie nicht. Von zwei Kreisen liegt der Mittelpunkt auf der y~Achse, sie tangieren die x-Achse, aber schneiden sie nicht.
Das ergibt vier gleich große Schnittflächen. Ich möchte gerne die Gesamtfläche des Vierpass errechnen. Dazu brauche ich ja eigentlich nur den Kreisinhalt zu multiplizieren und die Schnittflächen davon zu substrahieren. Die vier Kreismittelpunkte sind zueinander als Quadrat angeordnet, eine Seitenlänge entspricht also dem Abstand .... ah... es geht mir ein Licht auf. d (also der Abstand zweier sich schneidender Kreise) kann errechnet werden, wenn man die Diagonale des Quadrats als Hypothenuse heranzieht. Oder eben d als Hypothenuse definiert und Quadratdiagonale/2 als a bzw. b (Satz des Pythagoras). Und die Diagonale des Quadrats entsprich 2*r. Danke, hilft manchmal schon, wenn man irgendwo ein Problem schildern kann. Sorry, wenn die Terminologie nicht stimmt, Abi ist mehr als zwei Jahrzehnte her und in Mathe war ich nie gut.
Hallo Walter,
sorry, ich habe kein Kommentar, sondern eine relevante Frage. Mich interessieren die Schnittflächen der Kreise, weil Hana, meine Frau, als Bildhauerin Lentoide als modulare Körper in ihren geometrischen Kunstwerken zusammenstellt: www.hana-hasilik.de
Ich fand keinen Trivialnamen der Schnittfläche von Kreisscheiben. Leider habe ich nur 1962-Bratislava-Abi-Kenntnisse von Geometrie. Daher meine Frage: Gibt es eine Benennung im Deutsch oder in anderen Sprachen? Für einen Hinweis wäre ich sehr dankbar.
Beste Grüße aus Marburg
Andrej
Laut ChatGPT: Die Schnittfläche zweier Kreise wird als Kreissegment oder genauer als gemeinsames Kreissegment bezeichnet.