Kreiswinkel Punkt Kreis

Hallo.
Ich habe folgendes Problem:

Gegeben ist Mittelpunkt und Radius Kreis 1, sowie das gleiche für Kreis 2.
Wenn ich nun die Kreise verbinden will mach ich:
line(k1.x, k1.y, k2.x, k2.y)

So, nun hab ich ne linie zwischen den beiden Mittelpunkten.
Jetz will ich aber, das die Linie erst am RAND der beiden Kreise
anfängt / endet. (So als ob es aussehen würde, als hätte ich erst
die Linie gemalt und diese dann mit den Kreisen teilübermalt).

Dazu brauche ich also den… Kreiswinkel… (ist er das?) zwischen dem
mittelpunkt des einen Kreises zum mittelpunkt des anderen - damit
ich dann mit k1.x + sin(winkelZuK2) * radius, k1.y + cos(winkelZuK2)
sowie k2.x + sin(winkelZuK1) * radius, k2.y + cos(winkelZuK1) an die beiden
randpositionen komme… geht das irgendwie, oder denk ichd a ganz falsch?

Ich hab schon versucht, aus den beiden Mittelpunkten eine gerade zu machen,
von dieser die steigung und den Winkel zur y achse zu berechnen, aber was bringt
mir der Winkel zur y achse, wenn ich den Kreiswinkel haben will?
(Dann muss ich erstens prüfen, ob sich überhaupt eine gerade bilden lässt, ansonsten
eben 0 oder 180 zurückgeben, und dann prüfen in welchem viertel sich der zweite punkt befindet,
also rechts oben, rechts unten, link unten, links oben, um damit was anfangen zu können…)

Hilft mir jemand auf die Sprünge? ^^

Danke!

Du musst genauer sein:

Wenn du zwei Kreise hast und einen Punkt auf einer Kreislinie P: dann gibt es genau eine Tangente durch den Punkt P, die muss mit dem anderen Kreis ja nichts zu tun haben.

Wenn du zwei Kreise hast und nur Geraden suchst, die Tangenten an beide Kreise sind: da gibt es im Allgemeinen vier davon (zwei äußere, zwei innere), die Konstruktionen findest du hier: http://schulmodell.eu/unterricht/84-unterrichtsfaecher/mathematik-unterricht/mathematik-themen/mathelexikon/1672-tangentenkonstruktionen-am-kreis.html

Was genau willst du denn machen?

Ich denke mit Zeichnen alleine kommst Du hier nicht weiter.

Was Du brauchst sind die beiden Punkte, an denen der gemeinsame Durchmesser die Kreislinien schneidet. Dann zeichnest Du die Linie nur zwischen diesen beiden Punkten.

Die Frage ist, wie berechnest Du die Schnittpunkte?

Nach Pytagoras kannst Du den Abstand der Mitelpunkte (a) berechnen.

Die x- und y-Koordinate alle Punkte auf der Linie sind direkt proportional zu ihrem Abstand vom Mittelpunkt des ersten Kreises.
(xr1-xm1)/(xm2-xm1) = r1/a | xr->X des Schnittpunktes, xm-> X des Mittelpunktes , r-> Radius

Der Rest ist simples Umformen und Ausrechnen.

bye
TT

Hallo,

Wenn ich bis hierhin alles richtig verstehe, haben wir dein Problem alle anders verstanden :smiley:
Vielleicht solltest du es noch einmal ausführlich erläutern.

Ich verstehe es so, dass du zwei Kreise hast, die Gerade zwischen ihren Mittelpunkten zeichnen möchtest, allerdings nur von Rand zu Rand, also zwischen den Punkten, wo die Gerade die Kreise schneidet. (Bzw. nur zwei dieser vier Punkte.)

Wenn dem so ist:
Sagt dir Vektorrechnung etwas? Damit wird das ganze sehr leicht:

Du hast einen Kreis [TEX]$K_1$[/TEX] mit Radius [TEX]$r_1$[/TEX] und Mittelpunkt [TEX]$\left(\begin{array}{c}x_1\y_1\end{array}\right)$[/TEX] und einen zweiten Kreis [TEX]$K_2$[/TEX] mit Radius [TEX]$r_2$[/TEX] und Mittelpunkt [TEX]$\left(\begin{array}{c}x_2\y_2\end{array}\right)$[/TEX].

[ol]
[li]Berechne den Verbindungsvektor [TEX]$\vec{v}$[/TEX] zwischen [TEX]$\left(\begin{array}{c}x_1\y_1\end{array}\right)$[/TEX] und [TEX]$\left(\begin{array}{c}x_2\y_2\end{array}\right)$[/TEX]. ([TEX]$\vec{v}$[/TEX] hat auch die Form [TEX]$\left(\begin{array}{c}x\y\end{array}\right)$[/TEX], ist ja ein Vektor.)[/li][li]Berechne die Länge [TEX]$d$[/TEX] des Vektors [TEX]$\vec{v}$[/TEX].[/li][li]Skaliere den Vektor [TEX]$\vec{v}$[/TEX] auf die Länge von [TEX]$r_1$[/TEX]: [TEX]$\vec{v_1} = \frac{r_1}{d}\vec{v}$[/TEX].[/li][li]Berechne [TEX]$\vec{v_2}$[/TEX] analog zu [TEX]$\vec{v_1}$[/TEX].[/li][li]Der Punkt auf dem Kreis [TEX]$K_1$[/TEX], der auf der Geraden durch die Mittelpunkte [TEX]$\left(\begin{array}{c}x_1\y_1\end{array}\right)$[/TEX] und [TEX]$\left(\begin{array}{c}x_2\y_2\end{array}\right)$[/TEX] liegt, ist dann [TEX]$\left(\begin{array}{c}x\y\end{array}\right) = \left(\begin{array}{c}x_1\y_1\end{array}\right) + \vec{v_1}$[/TEX].[/li][li]Der Punkt auf [TEX]$K_2$[/TEX] berechnet sich genauso: [TEX]$\left(\begin{array}{c}x\y\end{array}\right) = \left(\begin{array}{c}x_2\y_2\end{array}\right) - \vec{v_2}$[/TEX].[/li][/ol]

Der Vorteil gegenüber Steigungen ist, dass du keine Probleme mit unendlichen Steigungen bekommen wirst.

LG
eitelkalk

Ach so, die Verbindungslinie zwischen den Mittelpunkten soll nur von Kreislinie1 bis Kreislinie2 gezeichnet werden?

berechne den betrag d von m2-m1, bei dir ist d also die Wurzel von (k1.x-k2.x)^2+(k1.y-k2.y)^2 (=Entfernung der Mittelpunkte)

die Gerade in Parameterform g(t)=m1+t*(1/d)(m1-m2) läuft mit Geschwindigkeit 1 bei t=0 durch m1, und bei t=d durch m2

zeichne sie von t=r1 bis t=d-r2, d.h. die Gerade durch die beiden Punkte

m1+(r1/d)(m2-m1)

und

m1+((d-r2)/d))(m2-m1)

Die Mathematiker mal kurz weghören: Oft kann man die Kreise einfach (gefüllt) über die (vorher gemalte) Linie drüberpinseln :smiley:

Wenn nicht, dann das, was schon vorher gesagt wurde.

Ich hab das für ein Programm, das Graphen darstellt, früher mal in Code gegossen. Wegen der Pfeilspitzen für gerichtete Kanten kann man da die Kreise nicht einfach drüber malen. Wenn du willst, kann ich das mal ausgraben, aber die theoretischen Grundlagen sollten oben ja stehen (habe es nur überflogen).

“Die Mathematiker mal kurz weghören: Oft kann man die Kreise einfach (gefüllt) über die (vorher gemalte) Linie drüberpinseln*”

Ja, mir gings aber darum mal nicht zu cheaten und eben dieser punkte zu berechnen ^^ oder wie crian sagte, manchmal braucht man die auch wirklich.
(Ich brauchte die gestern eigentlich gar nicht -.- hab was komplett anderes ausprobiert, und mich mitten drin davon ablenken lassen…)

Okay, danke euch.
Naja leider bin ich immer noch ziemlich unfit in vektorrechnung, weil ich mkr das bisher nur grob fuer 3d angeschaut hab, in der schule hatten wirs leider noch nicht ^^ es sieht aber so aus, als sei das hier die eleganteste loesung. (Ich hab mir auch schon gedacht, im prinzip muss ich ja vom mittelpu kt aus eibfach radius in richtung andeder nittelunpunkt gehen…)

Ich melde mich wieder wenn ichs ausproviert hab ^^

@Crian : Das habe ich auch mal gemacht. Mit Graphen und Knoten und Kanten und Pfeilen. Allerdings… waren die Pfeile da gebogen, weil man ja sonst nicht sinnvoll mehrere Pfeile zwischen zwei Knoten haben kann. Und die Knoten waren als Shape repräsentiert, weil man oft ja z.B. Rectangles oder RoundRectangles haben will, um z.B. Text reinzuschreiben und keinen Platz zu verschwenden. Mit anderen Worten lief das darauf raus, den Schnittpunkt zwischen einem Path2D und einem Shape zu berechnen. Das ist dann aber in mancher Hinsicht “einfach”, weil man es ohnehin nicht Mathematisch machen kann, sondern das ganze mit PathIteratoren zerstückeln muss. (Auf unterester Ebene kommt dann zwar die LineSegment-LineSegment-Schnittpunktberechnung dazu, aber da gibt’s fertige Lösungen)

OT: Hättest du nicht einfach mathematisch berechnete splines benutzen können?
Da ließe sich doch dann etwas mit mathematik machen…

Danke!
Ich habs hinbekommen mit Vektoren, aber auch den anderen vielen Dank.

Unter anderem noch einmal Danke, weil ich endlich Vektoren richtig verstanden habe…
übernächstes halbes Jahr Mathe - easy ^^

Jedenfalls, manchmall gibt es kleinere Fehligkeiten, aber ich denke die kann man nicht
fixen wenn man nicht den Swing Antialiasing Code kennt, von daher ist das ok:

(man sieht das beim unteren und rechten kreis ein pixel zu viel gezeichnet wurde)

So, genug mathe für heute ^^

[quote=mymaksimus]man sieht das beim unteren und rechten kreis ein pixel zu viel gezeichnet wurde[/quote]Zeichne den schwarzen Kreis mal in rot. Ich vermute, dass die beiden Linien oben und links auch ein Pixel zu lang sind…

bye
TT

wo du recht hast hast du recht…
und jetzt?

Naja wenn das wirklich immer so ist, kann ich ja einfach 1pixel in vektor richtung weiterlaufen…
oder was würdest du tun?

*** Edit ***

bzw moment. das ist ja eben auf 2 verschiedenen seiten…
aber wann jetzt wie?

[quote=mymaksimus]wo du recht hast hast du recht…
und jetzt?[/quote]Ist 'n Rundungsfehler, vermutlich am Startkreis (da wird beim cast zu int abgerundet, genauer der Nachkommateil abgeschnitten, obwohl’s nach oben gehen müsste…)

bye
TT

Ist das Bild in Originalgröße? D.h. es geht wirklich um einzelne Pixel?

ja.

@TT, ich versuch mal mit runden statt casten.
Ich caste die werte aber nur am ende, um sie zu zeichnen…
ich hab bisher immmer gecastet… vllt war das ja ein fehler ^^

*** Edit ***

Nene… mit runden ist es noch schlimmer,
da wird manchmal sogar einer zu wenig statt einer zu viel gezeichnet…
auch wenn das antialiasing aus ist…

Ich denke ich lass das so.
wie gesagt, eigentlich ist das bei der sache sowas von unbedeutend…

*** Edit ***

[Aber wenn jemand spontan weiß was der fehler aus, darf er das gerne raushauen ;)]

Vielleicht rundet ja die Funkton die die Kreise zeichnet? du kannst ja ganz am Ende mal die Strecke zwischen beiden Kreismittelpunkten minus die beiden Radien mit der Länge der gezeichneten Linie vergleichen

Ja, auf Pixelebene wird das mit der „definition of insideness“ (siehe http://docs.oracle.com/javase/8/docs/api/java/awt/Shape.html#def_insideness ) teilweise recht frickelig. Das Problem sollte aber nicht in dieser Form auftreten, wenn man

  • Die Kreise als Ellipse2D.Double repräsentiert
  • Die Linien als Line2D.Double repräsentiert
  • Den Schnittpunkt mit doubles ausrechnet :wink:
  • Das ganze mit ANTIALIASING_ON-RenderingHints zeichnet.

Wenn doch, wäre ein KSKB nicht verkehrt…

Auch mit dem ganzen java.awt.geom gefrickele gibt es diesen kleinen schönheitsfehler…


import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class Kskb extends JPanel {
	
	private double nodeRadius = 30.0;
	private Ellipse2D.Double center, c1, c2, c3;
	
	public Kskb(){
		c1 = new Ellipse2D.Double(100.45, 134.5232, nodeRadius * 2, nodeRadius * 2);
		c2 = new Ellipse2D.Double(200.721, 104.5232, nodeRadius * 2, nodeRadius * 2);
		c3 = new Ellipse2D.Double(400.923, 300.31215, nodeRadius * 2, nodeRadius * 2);
		center = new Ellipse2D.Double(300.235, 200.9125, nodeRadius * 2, nodeRadius * 2);
		buildGui();
	}
		
	private void buildGui(){
		JFrame f = new JFrame();
		f.setSize(800, 600);
		f.setLocationRelativeTo(null);
		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		f.add(this);
		f.setVisible(true);
	}
	
	protected void paintComponent(Graphics g){
		super.paintComponent(g);
		Graphics2D g2d = (Graphics2D) g;
		g2d.setColor(new Color(39, 40, 34));
		g2d.fillRect(0, 0, getWidth(), getHeight());
		g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
		g2d.setColor(new Color(61, 154, 179));
		
		g2d.fill(c1);
		g2d.fill(c2);
		g2d.fill(c3);
		g2d.setColor(new Color(61, 179, 51));
		g2d.fill(center);
		g2d.setColor(Color.BLACK);
		drawLineBetweenCircles(g2d, center, c1);
		drawLineBetweenCircles(g2d, center, c2);
		drawLineBetweenCircles(g2d, center, c3);
	}
		
	private void drawLineBetweenCircles(Graphics2D g2d, Ellipse2D.Double e1, Ellipse2D.Double e2){
		double connectionVectorX = e2.getCenterX() - e1.getCenterX();
		double connectionVectorY = e2.getCenterY() - e1.getCenterY();
		double connectionVectorLength = Math.sqrt(connectionVectorX * connectionVectorX + connectionVectorY * connectionVectorY);
		double startX = e1.getCenterX() + connectionVectorX * nodeRadius / connectionVectorLength;
		double startY = e1.getCenterY() + connectionVectorY * nodeRadius / connectionVectorLength;
		double endX = e2.getCenterX() - connectionVectorX * nodeRadius / connectionVectorLength;
		double endY = e2.getCenterY() - connectionVectorY * nodeRadius / connectionVectorLength;
		g2d.draw(new Line2D.Double(startX, startY, endX, endY));
	}
	
	public static void main(String[] args){
		new Kskb();
	}
}

Wundert mich etwas - insebsondere dass beim grünen Kreis rechts unten der Fehler auftritt, aber beim cyanenen (!?) nicht, obwohl die Line fast gleich zu liegen scheint. Vielleicht schau’ ich da morgen nochmal genauer.