Kreis auf Linie platzieren (-> Koordinatentransformation?)

Hallo!

Ich bins mal wieder ^^

Diesmal will ich einen Kreis auf einer Linie platzieren. Und zwar an einem bestimmten Punkt.
Der Kreis wird in seiner Bewegung die Linie schneiden.


(Grün = Boundingbox, Blauer Punkt = Koordinate des Kreises, Roter Punkt = Nähester Punkt zum Kreis)

Der Kreis schneidet vereinfacht gesagt die Linie im roten Punkt. Allerdings lässt sich das nicht vermeiden, dass der Kreis kurz durch die Linie schwebt.



Jetzt soll der Kreis auf die Linie platziert werden. Und zwar so, dass die Linie eine Tangente zum Kreis durch den roten Punkt ist!




Meine Idee:

Man sieht das einfach aus der sicht von der Linie. Damit müsste der Kreis jetzt nurnoch das kleine Stückchen nach oben (der Teil vom Kreis, der unter der Linie ist). Zu sehen in Bild 2.

Aber was heißt "y nach oben gesehen von der Linie" für das normale Koordinatensystem?

Jetzt weiß ich, dass es Koordinatentransformation gibt

Koordinatentransformation ? Wikipedia

Aber so richtig darauf anwenden kann ich das irgendwie nicht. ???:L

Hat einer von euch vielleicht schon Erfahrung damit gemacht?

Hier noch ein bisschen Code, damit ihr nen Bezugspunkt habt:

Java:
//Der Kreis
Object2D circle = this;
//Die Linie mit welcher der Kreis kollidiert
Line2D line = new Line2D.Double(200,300,Main.mousePosition[0],Main.mousePosition[1]);
//Der Mittelpunkt vom Kreis
Point2D center = new Point2D.Double(circle.getX()+circle.weidth/2, circle.getY()+circle.getHeigth()/2);

//Radius vom Kreis	
double r = 25;
	
//Nähester Punkt zum Kreis (der rote)	
Point2D closest = Collision.closestPointToLine(line, center);

//Kollisionserkennung
if(closest.distanceSq(center) < r*r)
{
//System.out.println("Collision!");
//Jetzt müsste man den Kreis auf die Linie setzen!!! <----------------------------------
}

//MALEN (Nur die Punkte, Linie und Bounding Box)	    
g2.setPaint(Color.red);
g2.fill(new Ellipse2D.Double(closest.getX()-2, closest.getY()-2, 4, 4));
		
g2.setPaint(Color.green);
g2.draw(circle.getShape().getBounds2D());
		
g2.setPaint(Color.blue);
g2.fill(new Ellipse2D.Double(circle.getPos()[0]-2, circle.getPos()[1]-2, 4, 4));
		
g2.setPaint(Color.black);
g2.draw(line);
g2.fill(new Ellipse2D.Double(center.getX()-2, center.getY()-2, 4, 4));

MfG, Lurchi :rtfm:
 
Jetzt soll der Kreis auf die Linie platziert werden. Und zwar so, dass die Linie eine Tangente zum Kreis durch den roten Punkt ist!
falls ich die Aufgabe richtig verstanden habe, steht hier schon die ganze Lösung.

Meine Idee:

Man sieht das einfach aus der sicht von der Linie. Damit müsste der Kreis jetzt nurnoch das kleine Stückchen nach oben (der Teil vom Kreis, der unter der Linie ist). Zu sehen in Bild 2.

Aber was heißt "y nach oben gesehen von der Linie" für das normale Koordinatensystem?
Du musst in Vektoren denken. Zwischen Punkt Blau und Rot liegt ein Vektor, welcher senkrecht zum der Linie stehen muss. Weiterhin muss dieser Vektor der Länge nach dem Radius des Kreises entsprechen.

Das Vorgehen wäre:

1. aus dem gegebenem blauen Punkt den nähersten Punkt (Rot) auf der Linie ermitteln. So bekommt man den Vektor zwischen Rot und Blau. Dieser ist senkrecht zu der Linie
2. mit Pythagoras die Länge des Vektors ermitteln
3. die Differenz zwischen der Länge des Vektors und des Radius des Punktes berechnen.
4. nach den Ergebnissen aus Punkt 3 einen neuen Vektor erstellen, mit welchem der Kreis verschoben wird.

Punkt 1 und 2 sind bereits im Quelltext enthalten. Es wird aber nur der Fall geprüft, ob der Kreis die Linie schneidet, nicht der Fall, ob der Kreis außerhalb der Linie liegt, also:

Java:
//Kollisionserkennung
if(closest.distanceSq(center) < r*r ||
   closest.distanceSq(center) > r*r)
{
//System.out.println("Collision!");
//Jetzt müsste man den Kreis auf die Linie setzen!!! <----------------------------------
}

// Alternativ

if(closest.distanceSq(center) != r*r)
{
//System.out.println("Collision!");
//Jetzt müsste man den Kreis auf die Linie setzen!!! <----------------------------------
}

Slawa
 
Zuletzt bearbeitet:
Du musst in Vektoren denken. Zwischen Punkt Blau und Rot liegt ein Vektor, welcher senkrecht zum der Linie stehen muss. Weiterhin muss dieser Vektor der Länge nach dem Radius des Kreises entsprechen.

Das Vorgehen wäre:

1. aus dem gegebenem blauen Punkt den nähersten Punkt (Rot) auf der Linie ermitteln. So bekommt man den Vektor zwischen Rot und Blau. Dieser ist senkrecht zu der Linie
2. mit Pythagoras die Länge des Vektors ermitteln
3. die Differenz zwischen der Länge des Vektors und des Radius des Punktes berechnen.
4. nach den Ergebnissen aus Punkt 3 einen neuen Vektor erstellen, mit welchem der Kreis verschoben wird.

Ich denke ich versteh das schon. Aber meinst du wirklich den blauen Punkt und nicht den Mittelpunkt vom Kreis?
Oder meinst du den blauen Punkt (also koordinaten vom kreis) und davon dann seperat wieder einen Punkt, der am nähesten auf der Linie liegt? (rot, allerdings nicht der im Bild)

Wenn ich dann die Differenz von der länge des Vektors und dem Radius habe. Wie erstell ich damit einen neuen Vektor? Das ist ja nur eine Zahl (Differenz) :rtfm:
 
Es ist die Differenz zwischen Kreismittelpunkt und dem roten Punkt gemeint. Wenn der Radius z.B. 20 ist, und der Abstand zwsichen Kreismittelpunkt und rotem Punkt ist nur 10, dann berechnet man die besagte Differenz (x,y), normiert die (teilt sie durch ihre Länge), und mutlipliziert den resultierenden Vektor mit 10 - da kommt dann raus, wie weit man den Kreis verschieben muss, damit er die Linie im roten Punkt berührt.
 
:applaus: oha jetzt gibts auf jeden fall ein gutes ergebnis danke 🙂

Allerdings hab ich das mulitplizieren vom vektor weggelassen. Mit wurde der Kreis immer ruckartig über die Linie gesetzt aber nicht auf die Linie.

Hier mal der Code

Java:
		double dx = center.getX() - closest.getX();
		double dy = center.getY() - closest.getY();
		double dis = center.distance(closest);
		Vektor v = new Vektor(dx, dy).normalize();
//Vektor v = new Vektor(dx, dy).normalize().times(dif); //multiplizieren?

		if(dis < r)
		{
			circle.setPos(circle.getPos()[0]+v.getX(), circle.getPos()[1]+v.getY());
			circle.moveVektor().set(0, 0);
			System.out.println("collision");
		}

Komisch ist jetzt allerdings noch, dass der Kreis sich recht langsam zu seiner posisiton bewegt.
Also er schneidet die Linie und fährt dann langsam zu der gewünschten Position.
Ist zwar zu verkraften aber an was liegt das?
 
So hat zwar etwas gedauert weil ich leider wenig zeit für das programm hatte...

dafür hab ich meinen fehler selbst gefunden 😉

Man muss den vektor noch mit (Radius - (Abstand zwsichen Kreismittelpunkt und rotem Punkt)) multiplizieren.
 

Zurück
Oben