603.337 aktive Mitglieder*
4.467 Besucher online*
Kostenfrei registrieren
Einloggen Registrieren

Schnittpunkt - zwei Kreise, Formeln?

Beitrag 30.08.2006, 15:18 Uhr
matthias-lrt
Level 1 = Community-Lehrling
*

hi

ich hab ne zeitlang versucht, eine eigene software zu entwickeln, die mir ein G-code in takt-/richtungssignale umwandelt. gescheitert bin ich dabei daran, dass ich es nicht geschaft hab, formeln zu finden um den schnittpunkt von 2 kreisen zu berechnen. meine versuche haben dabei immer früher oder später rechnungen enthalten, die dann zu brüchen über 3 zeilen mutiert sind ...
und jetzt hab ich gesehen, das hier auf der seite hier ein tool integriert ist, das genau das berechnen kann (kopfzeile: Berechnungen: Schnittpunkt - zwei Kreise)

meine Frage ist also nun, gibt es eine möglichkeit die formeln, die dahinter stecken zu bekommen? vielleicht kann mir ja jemand von den admins die geben?

gruß
matthias
TOP    
Beitrag 30.08.2006, 16:13 Uhr
CNCFanatiker
Level 8 = Community-Ehrenmitglied
Gruppensymbol

Hallo matthias-lrt!

Da musst du mit
Ulli reden. Ich glaube die Berechnung kommt von ihm.

Allerdings muss ich zu geben, dass mich die Berechnung auch interessieren würde - genauso wie die Berechnung des Schnittpunktes 2er Strecken. Also wenn da jemand bescheid weiß...?!


--------------------
Gruß / Regards
CNCFanatiker
AdminCrew

Wenn wir immer das tun was wir können, dann bleiben wir immer das was wir sind.
If we always this act what we are able to do, then we always remain what we are.
TOP    
Beitrag 30.08.2006, 17:05 Uhr
matthias-lrt
Level 1 = Community-Lehrling
*

hi

mit den 2 geraden des kann ich dir glaub ich erklären:

man nimmt es einfach als 2 vektor-geraden. jede dieser geraden braucht als definition einen punkt (xs|ys) und eine richtung (a), nach möglichkeit beides als vektoren. da hier nach dem grad winkel gefragt ist zur berechnung, wird dieser vermutlich erst noch umgewandelt in einen richtungsvektor.

daraus folgt nun als gerade:

G: p(t) = ( xs | ys ) + t * ( sin(a) | cos(a) )

wobei p(t) ein beliebiger punkt ist, der auf der gerade liegt.

nun ist aber gefragt nach dem schnittpunkt, also dem punkt den beide geraden gemeinsam haben.

also

G1 = G2

also

( xs1 | ys1 ) + t1 * ( sin(a1) | cos(a1) ) = ( xs2 | ys2 ) + t2 * ( sin(a2) | cos(a2) )

wenn man nun diese gleichung hat, kann man sie nach beginnen sie nach t1 und t2 auszurechnen. dazu zerlegt man sie in ein gleichungssystem (des geht, weil es Vektoren sind)

Gleichung 1:
xs1 + t1 * sin(a1) = xs2 + t2 * sin(a2)

umgeformt:

t1 * sin(a1) + t2 * -sin(a2) = xs2 - xs1

Gleichung 2:
ys1 + t1 * cos(a1) = ys2 + t2 * cos(a2)

umgeformt:

t1 * cos(a1) + t2 * -cos(a2) = ys2 - ys1

damit hat man nun 2 gleichungen mit 2 variablen. dabei sollte ein eindeutiges ergebnis rauskommen. (natürlich muss man vorher ausschließen, dass die geraden parallel oder identisch sind. also am anfang überprüfen, ob a1 gleich oder ungleich a2 ist. damit es einen schnittpunkt gibt, müssen sie ungleich sein.)

des auflösen hab ich jetzt auf einem blatt papier gemacht, weil es sonst zu tip intensiv wäre:

t2 = { [ ( ys2 - ys1 ) / cos(a1) ] - [ ( xs2 - xs1 ) / sin(a1) ] } / { [ sin(a2) / sin(a1) ] - [ cos(a2) / cos(a1) ] }

damit hat man jetzt einen der werte für t und den setzt man jetzt in die entsprechende gerade ein und rechnet es aus. damit hat man dann den punkt auf der einen gerade, und da bei der anderen gerade genau das gleiche rauskommen muss, braucht man den zweiten wert für t gar nicht mehr ausrechnen.

im programm sind die formeln dann natürlich nicht ganz so lang, da man teile vorher schon ausrechnen lassen kann und mit einer neuen variablen benennent. die setzt man dann einfach überall dort ein, wo es nötig wäre.

z.b.: var1 = ( xs2 - xs1 ) und dann überall wo eigentlich die klammer steht einfach nur var1 hingestzt.


ich hoff des war soweit verständlich und nicht zu kompliziert. eventuell gibt es noch einen einfacheren weg, aber das is halt der weg, wie ich es lösen würde.
vielleicht könnte man den computer es auch einfach ausprobieren lassen: er setzt irgenteinen wert für t ein und schaut, wie groß die entfernung zur anderen gerade ist. dann den nächsten wert. wenn abstand größer wird, dann muß der wert für t in die andere richtung verändert werden und so weiter ...


danke für den tip mit ulli. ich glaub ich schreib dem dann mal direkt die frage.

gruß
matthias
TOP    
Beitrag 30.08.2006, 17:55 Uhr
CNCFanatiker
Level 8 = Community-Ehrenmitglied
Gruppensymbol

Hallo matthias-lrt!

danke.gif für die Gleichungen und die Erklärung! Ich schau sie mir mal in Ruhe an - könnte ich gut für ein Parameterprogramm gebrauchen wenn das alles so klappt... Falls ich nicht so ganz durch sehe melde ich mich nochmal ...


--------------------
Gruß / Regards
CNCFanatiker
AdminCrew

Wenn wir immer das tun was wir können, dann bleiben wir immer das was wir sind.
If we always this act what we are able to do, then we always remain what we are.
TOP    
Beitrag 30.08.2006, 19:43 Uhr
Cooltyper
Level 2 = Community-Facharbeiter
**

Ich hatte mir schon mal die Arbeit gemacht. Ist schon Jahre her. Ich habe es damals in Pascal entwickelt und dann in CNC umgeschrieben. Habe es aber noch nicht oft benutzt, weil wir auf ein CAD-CAM-System umgestiegen sind. Ist aber leider nicht in G-Code, sondern in Klartext. Habe es aber zuhause in Word umgeschrieben, darum ist die Syntax noch etwas anders. Heißt, du mußt es von Hand eintippen und kannst es nicht einspielen. Aber vielleicht hilft es Dir ja:

-------------------------------------------
Schnittpunkte Kreise TNC 426

Beschreibung:
Berechnet die Schnittpunkte zweier Kreise. Das Programm benutzt den Befehlssatz der Heidenhain TNC 426 Steuerung.


Eingabe: q30, q31, q32 : X, Y, Radius von Kreis 1
q33, q34, q35 : X, Y, Radius von Kreis 2
Ausgabe: q40, q41 : X, Y von Schnittpunkt 1
q42, q43 : X, Y von Schnittpunkt 2
q44 : wenn keine Schnittpunkte vorhanden 0, sonst 1
Verluste: : q36, q37, q38, q39



q44:=0;
if q30<>q33 then goto 6;
if q31=q34 then goto 1;
6:
q36:=sqrt(sqr(q30-q33)+sqr(q31-q34));
q37:=(sqr(q36)+sqr(q32)-sqr(q35))/(2*q36);
q38:=q32+q35;
if q36>q38 then goto 1;
q38:=abs(q32-q35);
if q36<q38 then goto 1;
if q37>q32 then goto 1;
q44:=1;
q38:=aco(q37/q32);
q40:=q33-q30;
q41:=q34-q31;
q39:=90;
if q40=0 then goto 5;
q39:=ata(abs(q41)/abs(q40));
5:
if q40>0 then goto 3;
if q41<0 then goto 3;
if q41=0 then goto 3;
q39:=180-q39;
3:
if q40>0 then goto 4;
if q40=0 then goto 4;
if q41>0 then goto 4;
q39:=q39+180;
4:
if q40<0 then goto 2;
if q41>0 then goto 2;
if q41=0 then goto 2;
q39:=360-q39;
2:
q36:=q39-q38;
q40:=q30+co(q36)*q32;
q41:=q31+si(q36)*q32;
q36:=q39+q38;
q42:=q30+co(q36)*q32;
q43:=q31+si(q36)*q32;
1:
TOP    
Beitrag 30.08.2006, 19:56 Uhr
CNCFanatiker
Level 8 = Community-Ehrenmitglied
Gruppensymbol

@ Cooltyper

Hallo Cooltyper,

das ist ja spitze.gif - werds mal in die Phillips-Steurung hacken wenn ich mal ein 3D am laufen habe.. Bin mein eigener Postprozessor. tounge.gif
Hab aber frühestens in 3 Wochen erst wieder ein wenig Luft - zur Zeit habe ich zu viele Nebenbei-Projekte am laufen! Aber auf alle Fälle erst mal danke.gif !!!


--------------------
Gruß / Regards
CNCFanatiker
AdminCrew

Wenn wir immer das tun was wir können, dann bleiben wir immer das was wir sind.
If we always this act what we are able to do, then we always remain what we are.
TOP    
Beitrag 30.08.2006, 20:28 Uhr
matthias-lrt
Level 1 = Community-Lehrling
*

hi

@cooltyper danke auch von mir

da das ganze ja sowieso nicht in eine vorgefertigte maschine soll, war mir von anfang an klar, das ich es neu umschreiben muss. mir ging es dabei also mehr oder weniger um die mathematischen formeln. aber die kann ich aus deinem teil gut rauslesen. also danke nochmal thumbs-up.gif

nur noch kurz zur kontrolle:

sqr = quadrat
sqrt = quadratwurzel ziehen
aco = arcus cosinus
ata = arcus tangens
abs = betrag
si = sinus
co = cosinus
wenn der einen sprung mit einem goto befehl macht, läuft er dann alle befehlszeilen drunter ab, ungeachtet weiterer sprungmarken, auf die ihn kein goto weist?

ich glaub man merkt an den rückfragen, dass ich mit der sprache noch nicht gearbeitet hab, immer nur in c ...


gruß
matthias
TOP    
Beitrag 01.09.2006, 20:07 Uhr
Cooltyper
Level 2 = Community-Facharbeiter
**

Hi @matthias-lrt!!!

Die Kürzel, die Du beschrieben hast stimmen so alle. ABS ist der absolute Wert. Der absolute Wert ist immer positiv. Ich weiß nicht, ob Du mit Betrag das selbe meinst.

Zu dem Goto: Er Springt einfach auf die Sprungmarke. Sprungmarken selbst werden im Programm ignoriert. Meine Gotos verhalten sich so wie der C64-Goto und nicht wie der Gosub, wo bei irgendwelchen befehlen wieder zurückgesprungen wird.

Noch mal zu meinem Programm: Ich hab das Programm komplett aus Trigonometrie zusammengebastelt. Nicht irgendwie aus Formeln zusammengebaut und weggekürzt. Ich hab es auf alle eventualitäten getestet. Heißt: Kreise berühren sich in einem Punkt, Kreise liegen ineinander, auseinander untereinaner...... Vielleicht ist es in der Ausführungsgeschwindigkeit und Länge nicht das Beste, aber ich hab in Netz auch sonst nirgends einen Algolrythmus gefunden. Irgendwelche Mathematiker hauen einem da die Formeln um die Ohren, die man aber leider nicht annähernd in die Programme einbinden kann. Ich hab auch noch was mit Schnittpunt von zwei Linien gemacht. Falls Interesse besteht, setze ich es auch gerne hier rein.
TOP    
Beitrag 02.09.2006, 03:18 Uhr
paflo
Level 1 = Community-Lehrling
*

@Cooltyper

Das Thema ist komplexer. In Deiner Lösung werden keine Sonderfälle berücksichtigt.

Bei Zeit werde ich Deine Zeilen etwas überarbeiten.

Gruss Paul
TOP    
Beitrag 02.09.2006, 06:47 Uhr
Cooltyper
Level 2 = Community-Facharbeiter
**

@paflo

Ich hatte mir damals in Pascal ein Grafisches Programm geschrieben, wo ich die Kreise verschieben und im Radius ändern konnte. Ich habe alles mögliche durchgespielt. Es sieht etwas konfus aus, weil die CNC-Steuerung kaum als Hochsprache zu bezeichnen ist. Welchen Sonderfall hast Du denn gefunden, den meine Routine nicht berücksichtigt?

Achja, wenn Euer Programmiersystem die Winkelfunktionen im Bogenmaß berechnet, müßt ihr es erst umwandeln in Grad. (Winkel * Pi /180 glaube ich). Wie es in Basic aussieht, kann ich Euch auch noch hier reinmailen.
TOP    
Beitrag 02.09.2006, 09:42 Uhr
matthias-lrt
Level 1 = Community-Lehrling
*

hi

ich bin es jetzt mal druchgegangen und habs in ne andere sprache © umformuliert:



#include <math.h>

#define pi 3.14159;

main()
{
float xm1, ym1, r1, xm2, ym2, r2, am1m2, q37, q38, q39, xs1, ys1, xs2, ys2, schnittp;
printf("\n\nSchnittpunkte von 2 Kreisen\n\nMittelpunkt und Radius von Kreis 1: X,Y,R ");
scanf("%f %f %f",&xm1, &ym1, &r1);
printf("\nMittelpunkt und Radius von Kreis 2: X,Y,R ");
scanf("%f %f %f",&xm2, &ym2, &r2);


schnittp = 0;
if ( (xm1 == xm2) && (ym1 == ym2) ) goto ende;
am1m2 = sqrt( ( ( xm1 - xm2 ) * ( xm1 - xm2 ) ) + ( ( ym1 - ym2 ) * ( ym1 - ym2 ) ) );
q37 = ( ( am1m2 * am1m2 ) + ( r1 * r1 ) - ( r2 * r2 ) ) / ( 2 * am1m2);
q38 = r1 + r2;
if ( am1m2 > q38 ) goto ende;
q38 = abs( r1 - r2 );
if ( am1m2 < q38 ) goto ende;
if ( q37 > r1 ) goto ende;
schnittp = 1;
q38 = ( acos( q37 / r1 ) * 180 ) / pi;
xs1 = xm2 - xm1;
ys1 = ym2 - ym1;
if ( xs1 == 0 ) q39 = 90;
else q39 = ( atan( abs( ys1 ) / abs( xs1 ) ) * 180 ) / pi;
if ( !( xs1 > 0 ) && !( ys1 < 0 ) && !( ys1 == 0 ) ) q39 = 180 - q39;
if ( !( xs1 > 0 ) && !( xs1 == 0 ) && !( ys1 > 0 ) ) q39 = 180 + q39;
if ( !( xs1 < 0 ) && !( ys1 > 0 ) && !( ys1 == 0 ) ) q39 = 360 - q39;
am1m2 = ( (q39 - q38) / 180 ) * pi ;
xs1 = xm1 + cos( am1m2 ) * r1;
ys1 = ym1 + sin( am1m2 ) * r1;
am1m2 = ( (q39 + q38) / 180 ) * pi ;
xs2 = xm1 + cos( am1m2 ) * r1;
ys2 = ym1 + sin( am1m2 ) * r1;

ende:

if ( schnittp == 0 ) printf("\n\nErgebnis: keine Schnittpunkte der Kreise vorhanden");
else
{
if ( ( xs1 == xs2 ) && ( ys1 == ys2 ) ) printf("\n\nErgebnis: 1 Schnittpunkt vorhanden bei\nX%f Y%f",xs1,ys1);
else printf("\n\nErgebnis: 2 Schnittpunkte vorhanden bei\nX%f Y%f\nund bei\nX%f Y%f",xs1,ys1,xs2,ys2);
}
getch();
}



und es funktioniert smile.gif hab mir einfach mal 2 kreise schneiden lassen und es im acad nachgezeichnet. der hatte die gleichen werte.
dadurch das ich komplexere if funktionen erstellen konnte, wurde das programm auch fast alle sprungmarken los smile.gif nur um die letzte rauszubekommen, hätte ich break befehle anwenden müssen und die mag ich nicht tounge.gif


danke nochmal cooltyper für das basisprogramm

gruß
matthias

p.s.: die radiant degree umwandlung hab ich immer mit in die trigo funktionen/zeilen integriert ...
TOP    
Beitrag 02.09.2006, 10:33 Uhr
Speedcad
Level 3 = Community-Techniker
***

Ist natürlich Compiler Sache, in Visualstudio z.B. muss abs durch fabs ersetzt werden.
(Weil, Floating-point value und so)
Sqrt ist eigentlich für double sollte mit cast verwendet werden oder verwende sqrtf.


Und was ist mit Kreisbögen? . Wie bekommt man raus ob der Schnitt-Punkt auf dem Kreisbogen liegt?
QUOTE
ch hab ne zeitlang versucht, eine eigene software zu entwickeln, die mir ein G-code in takt-/richtungssignale umwandelt.

Nur der Neugierde wegen: Warum musstest du da eigentlich Schnittpunkte berechnen?
TOP    
Beitrag 02.09.2006, 11:29 Uhr
matthias-lrt
Level 1 = Community-Lehrling
*

hi

in turboc zumindest ist sqrt nicht für double! ich habs zuerst so gehabt, das alle variablen im format double waren, aber da is er mir immer am sqrt abgeschmiert, weil der n float wert braucht. aber wie du ja gesagt hast: is compiler sache ...

hmm, mit dem kreisbogen könnt man versuchen auszurechnen, bei welchem grad wert der schnittpunkt liegt und anschliesend überprüfen, ob dieser grad wert innerhalb des bogens liegt. müsste ungefähr so aussehen:
xs / ys / winkels sind die vom schnittpunkt
xm / ym sind die vom mittelpunkt
winkelbst ist der startwinkel vom bogen
winkelbe ist der endwinkel vom bogen
und schnittdrinnen ist 1 wenn es stimmt



winkels = ( acos( abs( xs - xm ) / abs( r ) ) * 180 ) / pi;
if( ( xs - xm <= 0 ) && ( ys - ym > 0 ) ) winkels = winkels + 90;
if( ( xs - xm <= 0 ) && ( ys - ym < 0 ) ) winkels = winkels + 180;
if( ( xs - xm >> 0 ) && ( ys - ym < 0 ) ) winkels = winkels + 270;

winkelbst = ( acos( abs( xbst - xm ) / abs( r ) ) * 180 ) / pi;
if( ( xbst - xm <= 0 ) && ( ybst - ym > 0 ) ) winkelbst = winkelbst + 90;
if( ( xbst - xm <= 0 ) && ( ybst - ym < 0 ) ) winkelbst = winkelbst + 180;
if( ( xbst - xm >> 0 ) && ( ybst - ym < 0 ) ) winkelbst = winkelbst + 270;

winkelbe = ( acos( abs( xbe - xm ) / abs( r ) ) * 180 ) / pi;
if( ( xbe - xm <= 0 ) && ( ybe - ym > 0 ) ) winkelbe = winkelbe + 90;
if( ( xbe - xm <= 0 ) && ( ybe - ym < 0 ) ) winkelbe = winkelbe + 180;
if( ( xbe - xm >> 0 ) && ( ybe - ym < 0 ) ) winkelbe = winkelbe + 270;

if( winkelbst >= winkelbe ) winkelbe = winkelbe + 360;
if( ( winkels >= winkelbst ) && ( winkels <= winkelbe ) schnittdrinnen = 1;
else schnittdrinnen = 0;


so ungefähr zumindest halt ...


die rechnungen brauchts in so einer software, um die radiuskorektur vorzunehmen, wenn 2 kreisbögen aufeinander folgen. man berechnet aus den i / j koordinaten die mittelpunkte und die radien, zählt zum radius den fräßerradius hinzu bzw. zieht ihn ab und kann damit dann die anzufahrenden punkte für nach der bahnkorrektur ausrechnen.

gruß
matthias
TOP    
Beitrag 02.09.2006, 12:08 Uhr
Speedcad
Level 3 = Community-Techniker
***

Aha du schaust in welchen Quadranten der Winkel liegt.
Bei dem Test wird aber die Laufrichtung(G2,G3) nicht berücksichtig , wenn ich das jetzt richtig sehe.

Gibt?s dafür keine sinnvolle mathematische Lösung bzw. elegante Formel?
TOP    
Beitrag 02.09.2006, 12:41 Uhr
matthias-lrt
Level 1 = Community-Lehrling
*

hi

nun die werden in soweit berücksichtigt, das ich ja geschrieben hab:
QUOTE
man berechnet aus den i / j koordinaten die mittelpunkte und die radien, zählt zum radius den fräßerradius hinzu bzw. zieht ihn ab und kann damit dann die anzufahrenden punkte für nach der bahnkorrektur ausrechnen.


des heißt alle radien die hier verwendet werden, um den quadranten, beziehungsweise erst mal den schnittpunkt zu berrechnen bereits daraufhin abgewandelt worden sind, ob sie um den fräßerradius kleiner oder größer werden müssen.
z.b. G02 und G41: rkreis + rfräß = r
aber G03 und G41: rkreis - rfräß = r
natürlich muss da vorher noch überprüft werden, ob rkreis > rfräß, weil sonst kann es ja nicht gefahren werden.

gruß
matthias
TOP    
Beitrag 02.09.2006, 13:16 Uhr
Speedcad
Level 3 = Community-Techniker
***

Achso, du setzt quasi die Einheitliche Laufrichtung für die Rechnung schon voraus.

QUOTE
if( ( xs - xm <= 0 ) && ( ys - ym < 0 ) ) winkels = winkels + 180;


ich glaube das passt so nicht wenn (ys ? ym) ==0 dann gibt es doch Fehler oder nicht?

Kleiner Tipp acos erzeugt Fehler wenn Werte <1 o. >1 übergeben werden.
Das kann bei solchen Rechnungen wegen der Fleißkommtoleranz durch auspassieren.
Für solche Zwecke habe ich ein Spezial-ACOS.


inline double ACOS(double B)
{
if(B<-1.0)
return 3.1415926535897932384626433832795;//entspricht genau 180 °

if(B>1.0)
return 0.0;

return acos(B);
}
TOP    
Beitrag 02.09.2006, 13:41 Uhr
matthias-lrt
Level 1 = Community-Lehrling
*

hi

stimmt, muss bei den zeilen mit +180 ( ys - ym ) <= 0 heißen damit er n waagrechtes auch anerkennt. wie gesagt: so ungefähr halt ...

hmm, mit deiner vers vom acos hat es aber eventuel n kleines problem: was ist, wenn es gar kein ergebnis geben soll, weil es aufgrund der sonstigen parameter dazu kommt.

gruß
matthias
TOP    
Beitrag 02.09.2006, 13:43 Uhr
matthias-lrt
Level 1 = Community-Lehrling
*

hi

mir ist grad noch aufgefallen: man muss eventuel noch ausschließen, ob der schnittpunkt auf dem mittelpunkt liegt. aber dazu müsste ja einer der radiuse 0 sein. also auch nur eventuel ...

gruß
matthias
TOP    
Beitrag 02.09.2006, 14:11 Uhr
Speedcad
Level 3 = Community-Techniker
***

Das ist so gemeint,
wenn man dieverse Winkel ausrechnen will,
kommen manchmal Werte zustande die in etwa so sind "-1.00000001" das soll ein Winkel von 180 grad sein, acos würde jetzt aber (Floating overflow o. ähnlich). Fehler zurück liefern damit kommen dann schwer lokalisierbare Fehler zu Tage.

Enstehen kann das so:
abs( xbst - xm ) / abs( r ) )
abs(0-1)/abs(0.999999999)

eigentlich müsste r ja auch 1 sein aber wegen ungenauer Ausgangsdaten(z.B. NC Daten) oder Rundungsfehler ist eben nichtgenau 1. acos muß jetzt mit: ?acos(1.00000001)? rechnen.
Acos liefert jetzt einen Fehler zurück .
Gemeint ist aber 1.0 -> raus kommen würde dann 0.0 (Bogenmaß), bei -1.0 dann genau PI (Bogenmaß für 180 Grad) .

Da für die Winkel-Rechnung nur Werte zwischen ?1 und 1 gültig sind, kann man das so korrigieren.
TOP    
Beitrag 02.09.2006, 14:41 Uhr
matthias-lrt
Level 1 = Community-Lehrling
*

hi

ok, verstanden was du meinst smile.gif

das läuft im endeffekt darauf hinaus, wie man früher taschenrechner getestet hat. man hat ihn einfach immer wieder cos arccos cos arccos ... machen lassen (alternativ auch sin oder wurzel und quadrat), und hat geschaut wie weit es wann vom ausgangswert abweicht.

ich bin aber auch schon auf den nächsten interessanten punkt gestoßen, was das schnittpunkt suchen angeht:
ein Kreis soll eine Gerade schneiden. ist glaub ich sogar noch einfach zu lösen als der teil mit den zwei kreisen. also mal probieren.

gruß
matthias
TOP    
Beitrag 02.09.2006, 15:27 Uhr
matthias-lrt
Level 1 = Community-Lehrling
*

hi

smile.gif lösung gefunden kann jetzt kreise und geraden schneiden smile.gif


#include <math.h>

main()
{
float xst, yst, xv, yv, xm, ym, r, xp, yp, xs1, ys1, xs2, ys2, t, schnittp, spm, sps, sv;
printf("\n\nSchnittpunkt eines Kreises und einer Geraden\n\nMittelpunkt und Radius des Kreises: X Y R ");
scanf("%f %f %f", &xm, &ym, &r);
printf("\nPunkt durch den die Gerade geht: X Y ");
scanf("%f %f", &xst, &yst);
printf("\nRichtung der Geraden: Dx Dy ");
scanf("%f %f", &xv, &yv);


schnittp = 0;
t = ( ( xm - xst ) * xv + ( ym - yst ) * yv ) / ( ( yv * yv ) + ( xv * xv ) );
xp = xst + t * xv;
yp = yst + t * yv;
spm = sqrt( ( ( xp - xm ) * ( xp - xm ) ) + ( ( yp - ym ) * ( yp - ym ) ) );
if( ( spm > r ) || ( spm < -r ) ) goto ende;
schnittp = 1;
if( ( spm == r ) || ( spm == -r ) ) goto ende;
schnittp = 2;
sps = sqrt( ( r * r ) - ( spm * spm ) );
sv = sqrt( ( xv * xv ) + ( yv * yv ) );
xv = xv / sv;
yv = yv / sv;
xs1 = xp + sps * xv;
xs2 = xp - sps * xv;
ys1 = yp + sps * yv;
ys2 = yp - sps * yv;

ende:

if( schnittp == 0 ) printf("\n\nErgebnis: keine Schnittpunkte vorhanden");
else
{
if( schnittp == 1 ) printf("\n\nErgebnis: ein Schnittpunkt vorhanden bei\nX%f Y%f",xp,yp);
else printf("\n\nErgebnis: zwei Schnittpunke vorhanden bei\nX%f Y%f\nund bei\nX%f Y%f",xs1,ys1,xs2,ys2);
}
getch();
}



hat beim compilern sogar nur 3 tipfehler angezeigt smile.gif

gruß
matthias
TOP    



1 Besucher lesen dieses Thema (Gäste: 1)
0 Mitglieder: