Schnittpunktberechnung



  • tach zusammen,

    also folgendes Problem besteht, am Mittwoch findet meine Präsentation statt. Die Aufgabe lautet, dass ich den Schnittpunkt zweier strecken (keine Geraden) in C zum laufen bekommen soll. Mathematisch hab ich es meineserachtens nach geschafft und auch zum größtenteils fertig geschrieben nur will es iwie nicht laufen. könnt ihr mir vllt auf die Sprünge helfen und mir sagen was eventl. zu tun ist...
    ja bin leider anfänger :S

    #include <stdlib.h>
    #include <stdio.h>

    struct point { float x, y; };
    /*
    * Parameter:
    * a, b: Punkte der Geraden 1
    * c, d: Punkte der Geraden 2
    * x: Schnittpunkt
    *
    * Rückgabewert:
    * 0: geraden sind parallel
    * 1: geraden schneiden sich in x
    * 2: geraden sind übereinander
    */

    int intersect(struct point * a, struct point * b, struct point * c, struct point * d, struct point * x)
    {
    float t, t1;

    t1 = d->x * b->y - d->y * b->x;

    t = d->y * (a->x - c->x) - d->x * (a->y - c->y);

    if(t1 == 0.0) {
    if(t == 0.0) {
    return 2; // gerade liegen aufeinander
    } else {
    return 0; // kein schnittpunkt
    }
    }

    t = t / t1;

    x->x = a->x + (b->x - a->x) * t;
    x->y = a->y + (b->y - a->y) * t;

    return 1;
    }

    int main(){

    /*
    struct point a = { 0, 0 };
    struct point b = { 2, 1 };
    struct point c = { 4, 0 };
    struct point d = { 1, 0 };
    //struct point x = { 0, 0 };
    */
    printf("Bitte gebe die Punkte für die erste Gerade ein:\n");
    scanf("%f %f", a,b);
    printf("Bitte gebe nun die Punkte für die zweite Gerade ein:\n");
    scanf("%f %f", c,d);

    switch(intersect(&a, &b, &c, &d, &x)) {
    case 0:
    printf("kein schnittpunkt (parallel)\n");
    break;
    case 1:
    printf("ein schnittpunkt: S(%f|%f)\n", x.x, x.y);
    break;
    case 2:
    printf("geraden liegen aufeinander\n");
    break;
    }
    getchar ();

    }


  • Mod

    Ist das nicht ziemlich eindeutig? Dein Compiler beschwert sich doch sicherlich darüber, dass a, b, c, d und x nicht existieren. Womit er recht hat, denn deren Deklaration hast du auskommentiert. Außerdem willst du doch vermutlich insgesamt 8 Werte lesen, nicht nur 4. Also für a.x, a.y, b.x, b.y, c.x, ...

    Sauberer wäre es übrigens, wenn du im Funktionskopf durch passende consts deutlich machen würdest, dass die ersten vier Parameter nicht geändert werden, der 5. jedoch schon. Oder übergib die Eingabestructs per value. Zwei kleine floats kann man auch mal eben komplett kopieren, das sollte sogar flotter sein als die indirekte Variante.



  • Beschreibe doch mal was nicht funktioniert.
    Was soll passieren und was passiert.

    Und bette deinen Code in cpp-Tags ein, dann bleibt die Fromatierung erhalten und man kann ihn dann besser lesen: Code markieren und den C/C++ Button unter den 🙂 😃 😉 anklicken.

    #include <stdlib.h>
    #include <stdio.h>
    
    struct point { float x, y; };
    /*
     * Parameter:
     * a, b: Punkte der Geraden 1
     * c, d: Punkte der Geraden 2
     * x: Schnittpunkt
     *
     * Rückgabewert:
     * 0: geraden sind parallel
     * 1: geraden schneiden sich in x
     * 2: geraden sind übereinander
     */
    
    int intersect(struct point * a, struct point * b, struct point * c, struct point * d, struct point * x)
    {
    	float t, t1;
    
    	t1 = d->x * b->y - d->y * b->x;
    
    	t = d->y * (a->x - c->x) - d->x * (a->y - c->y);
    
    	if(t1 == 0.0) {
    		if(t == 0.0) {
    			return 2; // gerade liegen aufeinander
    		} else {
    			return 0; // kein schnittpunkt
    		}
    	}
    
    	t = t / t1;
    
    	x->x = a->x + (b->x - a->x) * t;
    	x->y = a->y + (b->y - a->y) * t;
    
    	return 1;
    }
    
    int main(){
    
    /*
    	struct point a = { 0, 0 };
    	struct point b = { 2, 1 };
    	struct point c = { 4, 0 };
    	struct point d = { 1, 0 };
    	//struct point x = { 0, 0 };
    */
    	printf("Bitte gebe die Punkte für die erste Gerade ein:\n");
    	scanf("%f %f", a,b);
    	printf("Bitte gebe nun die Punkte für die zweite Gerade ein:\n");
    	scanf("%f %f", c,d);
    
    	switch(intersect(&a, &b, &c, &d, &x)) {
    		case 0:
    			printf("kein schnittpunkt (parallel)\n");
    			break;
    		case 1:
    			printf("ein schnittpunkt: S(%f|%f)\n", x.x, x.y);
    			break;
    		case 2:
    			printf("geraden liegen aufeinander\n");
    			break;
    	}
    getchar ();
    }
    

    Warum sind die Variablendefinitionen in main ausgeklammert?

    scanf erwaten bei %f einen Zeiger auf float und keine struct. Das sollte aber auch der Compiler anmeckern (mit einer Warnung).

    Wenn du schon bei den scanf bist, ersetzte doch gleich mal alle float durch double.



  • Man darf mittlerweile* auch structs an Funktionen direkt übergeben und auch zurückgeben. Man muss nicht den Umweg über Zeiger gehen.

    *mittlerweile bedeutet hier, seit Mitte der 1980. Spätestens aber seit C89



  • mhh genau die kringelt er mir ein also, a, b, c, d, und &x aber warum exsistieren sie nicht? sind doch da oder nicht.

    okay das heisst struct durch float ersetzen?

    #include <stdlib.h>
    #include <stdio.h>
    
    struct point { double x, y; };
    /*
     * Parameter:
     * a, b: Punkte der Geraden 1
     * c, d: Punkte der Geraden 2
     * x: Schnittpunkt
     *
     * Rückgabewert:
     * 0: geraden sind parallel
     * 1: geraden schneiden sich in x
     * 2: geraden sind übereinander
     */
    
    int intersect(struct point * a, struct point * b, struct point * c, struct point * d, struct point * x)
    {
    	double t, t1;
    
    	t1 = d->x * b->y - d->y * b->x;
    
    	t = d->y * (a->x - c->x) - d->x * (a->y - c->y);
    
    	if(t1 == 0.0) {
    		if(t == 0.0) {
    			return 2; // gerade liegen aufeinander
    		} else {
    			return 0; // kein schnittpunkt
    		}
    	}
    
    	t = t / t1;
    
    	x->x = a->x + (b->x - a->x) * t;
    	x->y = a->y + (b->y - a->y) * t;
    
    	return 1;
    }
    
    int main(){
    
    /*
    	struct point a = { 0, 0 };
    	struct point b = { 2, 1 };
    	struct point c = { 4, 0 };
    	struct point d = { 1, 0 };
    	//struct point x = { 0, 0 };
    */
    	printf("Bitte gebe die Punkte für die erste Gerade ein:\n");
    	scanf("%f %f", a,b);
    	printf("Bitte gebe nun die Punkte für die zweite Gerade ein:\n");
    	scanf("%f %f", c,d);
    
    	switch(intersect(&a, &b, &c, &d, &x)) {
    		case 0:
    			printf("kein schnittpunkt (parallel)\n");
    			break;
    		case 1:
    			printf("ein schnittpunkt: S(%f|%f)\n", x.x, x.y);
    			break;
    		case 2:
    			printf("geraden liegen aufeinander\n");
    			break;
    	}
    getchar ();
    
    }
    


  • fola schrieb:

    mhh genau die kringelt er mir ein also, a, b, c, d, und &x aber warum exsistieren sie nicht? sind doch da oder nicht.

    Nein, denn du hast sie ja auskommentiert in den Zeilen 47-51

    Zudem sind deine Zeilen 54 und 56 falsch.


  • Mod

    fola schrieb:

    mhh genau die kringelt er mir ein also, a, b, c, d, und &x aber warum exsistieren sie nicht? sind doch da oder nicht.

    Merke: Wenn dein Compiler sich beschwert und dazu noch im Forum eine Erklärung kommt, dann kannst du davon ausgehen, dass du vielleicht mit deinem Standpunkt nicht richtig liegst. Insbesondere der Compiler hat immer Recht.

    Deine Deklarationen sind, wie schon 2x gesagt, ausgeklammert.

    okay das heisst struct durch float ersetzen?

    Antworten bitte genau lesen, die meisten Leute hier drücken sich auch mathematisch genau aus, da ist jedes Wort wichtig:

    Wenn du schon bei den scanf bist, ersetzte doch gleich mal alle float durch double.

    Wobei mir das an deiner Stelle hier egal wäre.



  • Warum sind die Variablendefinitionen in main ausgeklammert?

    weil es drei verschiedene ausgabesituationen geben soll. die strecken schneiden sich (ideallerweise) die strecken schneiden sich nicht und die strecken sind parallel.
    weis leider nicht wie ich es anders schreiben soll, und warum sollen zeile 54-56 falsch sein.

    sind bloß fragen meiner unwissenheit nicht aufregen 🙂



  • fola schrieb:

    Warum sind die Variablendefinitionen in main ausgeklammert?

    Die Variablendefinitionen sind auskommentiert durch /* */.
    Der Compiler beachtet sie gar nicht.

    ... und warum sollen zeile 54-56 falsch sein.

    scanf() erwartet Zeiger als Argumente.



  • also hab es den doch nochmal anders gemacht... aber jetzt schließt er mir die anwendung und sagt code 0 was will der von mir

    #include <stdio.h>
    #include <math.h>
    int main (void)
    
    	   /* Hier werden als erstes die Angaben gemacht */
    {
    double x1, y1, x2, y2, x3, y3, x4, y4, m1, m2, n1, n2, Ergebnisx, Ergebnisy;
    
         printf ("Geben Sie fuer Strecke 1 x1 ein: \n");
    	 scanf ("%lf", &x1);
    	 printf ("Geben Sie fuer Strecke 1 y1 ein: \n");
    	 scanf ("%lf", &y1);
    	 printf ("Geben Sie fuer Strecke 1 x2 ein: \n");
    	 scanf ("%lf", &x2);
    	 printf ("Geben Sie fuer Strecke 1 y2 ein: \n");
    	 scanf ("%lf", &y2);
    	 printf ("Geben Sie fuer Strecke 2 x3 ein: \n");
    	 scanf ("%lf", &x3);
    	 printf ("Geben Sie fuer Strecke 2 y3 ein: \n");
    	 scanf ("%lf", &y3);
    	 printf ("Geben Sie fuer Strecke 2 x4 ein: \n");
    	 scanf ("%lf", &x4);
    	 printf ("Geben Sie fuer Strecke 2 y4 ein: \n");
    	 scanf ("%lf", &y4);
    printf ("a=%f nb=%f nc=%f n",x1, y1, x2, y2, x3, y3, x4, y4);
    
    {
    	m1= (y2-y1)/(x2-x1);   /* berechnung der Steigung der Geraden */
    	m2= (y4-y3)/(x4-x3);
    
    	if (m1 == m2)
    		printf("Strecken sind Parallel");
    	else
    	if (n1 < n2)
    		printf("%lf schneiden sich nicht %lf \");
    
    	n1= y1-(y2-y1)/(x2-x1)*x1;          /* Abstände zur x-Achse */
    	n2= y3-(y4-y3)/(x4-x3)*x3;
    
    	Ergebnisx = (n2-n1)/(m1-m2);        /* berechnung der Scnittpunkte für x und y Koordinaten */
        Ergebnisy = m1*(n2-n1)/(m1-m2)+n1;
    
    	printf("Schnittkoardinate fuer x betraegt: %lf/n", Ergebnisx);
    	printf("Schnittkoardinate fuer y betraegt: %lf/n", Ergebnisy);
    }
    
    		getchar ();
    }
    


  • Teilst du irgendwo durch 0 ?


  • Mod

    fola schrieb:

    also hab es den doch nochmal anders gemacht... aber jetzt schließt er mir die anwendung und sagt code 0 was will der von mir

    #include <stdio.h>
    #include <math.h>
    int main (void)
    
    	   /* Hier werden als erstes die Angaben gemacht */
    {
    double x1, y1, x2, y2, x3, y3, x4, y4, m1, m2, n1, n2, Ergebnisx, Ergebnisy;
    
         printf ("Geben Sie fuer Strecke 1 x1 ein: \n");
    	 scanf ("%lf", &x1);
    	 printf ("Geben Sie fuer Strecke 1 y1 ein: \n");
    	 scanf ("%lf", &y1);
    	 printf ("Geben Sie fuer Strecke 1 x2 ein: \n");
    	 scanf ("%lf", &x2);
    	 printf ("Geben Sie fuer Strecke 1 y2 ein: \n");
    	 scanf ("%lf", &y2);
    	 printf ("Geben Sie fuer Strecke 2 x3 ein: \n");
    	 scanf ("%lf", &x3);
    	 printf ("Geben Sie fuer Strecke 2 y3 ein: \n");
    	 scanf ("%lf", &y3);
    	 printf ("Geben Sie fuer Strecke 2 x4 ein: \n");
    	 scanf ("%lf", &x4);
    	 printf ("Geben Sie fuer Strecke 2 y4 ein: \n");
    	 scanf ("%lf", &y4);
    printf ("a=%f nb=%f nc=%f n",x1, y1, x2, y2, x3, y3, x4, y4);
    
    {
    	m1= (y2-y1)/(x2-x1);   /* berechnung der Steigung der Geraden */
    	m2= (y4-y3)/(x4-x3);
    
    	if (m1 == m2)
    		printf("Strecken sind Parallel");
    	else
    	if (n1 < n2)
    		printf("%lf schneiden sich nicht %lf \");
    
    	n1= y1-(y2-y1)/(x2-x1)*x1;          /* Abstände zur x-Achse */
    	n2= y3-(y4-y3)/(x4-x3)*x3;
    
    	Ergebnisx = (n2-n1)/(m1-m2);        /* berechnung der Scnittpunkte für x und y Koordinaten */
        Ergebnisy = m1*(n2-n1)/(m1-m2)+n1;
    
    	printf("Schnittkoardinate fuer x betraegt: %lf/n", Ergebnisx);
    	printf("Schnittkoardinate fuer y betraegt: %lf/n", Ergebnisy);
    }
    	
    		getchar ();
    }
    

    Wie du alleine schon am Syntaxhighlighting hier im Forum siehst, ist der Code voller Schreibfehler. Das kann gar nicht übersetzen. Und selbst wenn man die Schreibfehler (Zeilen 27 und 39) wegmacht, bleiben sehr viele Compilerwarnungen:

    test.c: In function ‘main’:
    test.c:27:3: warning: too many arguments for format [-Wformat-extra-args]
       printf ("a=%f nb=%f nc=%f \n",x1, y1, x2, y2, x3, y3, x4, y4);
       ^
    test.c:39:9: warning: format ‘%lf’ expects a matching ‘double’ argument [-Wformat]
             printf("%lf schneiden sich nicht %lf \n");
             ^
    test.c:39:9: warning: format ‘%lf’ expects a matching ‘double’ argument [-Wformat]
             printf("%lf schneiden sich nicht %lf \n");
             ^
    test.c:52:1: warning: control reaches end of non-void function [-Wreturn-type]
     } 
     ^
    test.c:38:10: warning: ‘n1’ may be used uninitialized in this function [-Wuninitialized]
           if (n1 < n2)
              ^
    test.c:38:10: warning: ‘n2’ may be used uninitialized in this function [-Wuninitialized]
           if (n1 < n2)
              ^
    

    Die darfst du getrost alle als schwerwiegende Fehler ansehen, die dir der Compiler bloß nicht als Fehler ankreiden darf, da der Standard allerlei Unsinn erlaubt, in der Annahme der Programmierer wüsste schon, was er da tut. Das ist aber bei Anfänger nicht der Fall, daher Warnungen immer auf Maximum (auch als Profi) und Warnungen als Fehler ansehen.

    P.S.: Es ist furchtbar mit anzusehen, wie dein ursprüngliches Programm, das bis auf eine Kleinigkeit schon auf einem guten Weg zur Abstraktion war, nun zu diesem Ungeheuer geworden ist, da du an den Grundlagen scheiterst, wie man Werte einliest und ausgibt oder mit structs umgeht 😞 .



  • Füge in die Funktion main die Zeile: struct point a, b, c, d, x; ein. Damit deklarierst und definierst Du die Variablen. Scanf rufst Du wie folgt auf:
    scanf("%f %f %f %f", &a.x, &a.y, &b.x, &b.y);
    Scanf erwartet die Adressen der Variablen, daher der Adressoperator. Da der Punktoperator . stärker bindet als der Adressoperator, brauchst Du keine Klammern.
    Für die Variablen c und d machst Du das gleiche.
    Gruß
    Bonni4355



  • Bonni4355 schrieb:

    scanf("%f %f %f %f", &a.x, &a.y, &b.x, &b.y);

    Dann doch aber mit %lf, da ermitlerweile double nimmt.



  • DirkB schrieb:

    Bonni4355 schrieb:

    scanf("%f %f %f %f", &a.x, &a.y, &b.x, &b.y);

    Dann doch aber mit %lf, da ermitlerweile double nimmt.

    Hallo DirkB,
    ich bezog mich auf die ursprüngliche Fassung. struct point enthält 2 Variablen vom Typ float. Mit den Änderungen müsste das Programm compilierbar sein. Im übrigen sehe ich keine Notwendigkeit, hier float durch double zu ersetzen.
    Gruß
    Bonni4355



  • Hey, muss nächste Woche das gleiche Programm abgeben ^^
    Hab mir da was nettes zusammen geschrieben ...
    wenn Interesse besteht einfach melden.

    Gruß


Anmelden zum Antworten