Bresenham Algorithmus



  • pointercrash() schrieb:

    ...
    	// Führachse ermitteln
    	if ((*abs_x >= *abs_y) && (*abs_x >= *abs_z))
    		*leader = 'x';
    	else
    		if (*abs_y >= *abs_z)
    			*leader = 'y';
    		else
    			*leader = 'z';
    ...
    

    ...

    Schön ist diese Stelle im Code nicht.
    Und bitte, bitte keine Tabulatoren im Quellcode und bitte kein C-Chinesisch... in Anlehnung an die Diskussion hier http://www.c-plusplus.net/forum/viewtopic-var-t-is-229653-and-start-is-40-and-postdays-is-0-and-postorder-is-asc-and-highlight-is-.html



  • abc.w schrieb:

    Schön ist diese Stelle im Code nicht.

    stören dich die vielen sternchen?
    🙂



  • ~fricky schrieb:

    stören dich die vielen sternchen?
    🙂

    Nein, warum denn nicht so:

    *leader = ((*abs_x >= *abs_y) && (*abs_x >= *abs_z)) ? 'x' : (*abs_y >= *abs_z) ? 'y' : 'z';
    

    Aber jetzt im Ernst, ich würde natürlich diese ?: Kombination auch nicht akzeptieren.
    Ich habe nichts gegen if else if else Kombination. Es ist nur, dass man 2-3 mal drüberschauen muss, um zu erkennen, was pointercrash() da mit seiner Einrückung gemeint hat. Das ist nicht "soldatensicher" und auch nicht "idiotensicher". Und ich finde, der Konstrukt wäre auf folgende Weise optimal:

    if ((*abs_x >= *abs_y) && (*abs_x >= *abs_z))
    {
        *leader = 'x';
    }
    else if (*abs_y >= *abs_z)
    {
        *leader = 'y';
    }
    else
    {
        *leader = 'z';
    }
    


  • ^^du hast recht, es ist falsch eingerückt und ich bin voll drauf reingefallen.
    🙂



  • ~fricky schrieb:

    ^^du hast recht, es ist falsch eingerückt und ich bin voll drauf reingefallen.
    🙂

    Was heißt hier falsch eingerückt. Das was der Compiler da rausliest entspricht wohl eher der dargestellten Einrückung. Ich finde zwar auch, dass die andere Variante besser lesbar ist, aber "falsch" ist die dargestellte Einrückung sicher nicht.



  • Jester schrieb:

    ~fricky schrieb:

    ^^du hast recht, es ist falsch eingerückt und ich bin voll drauf reingefallen.

    Was heißt hier falsch eingerückt.

    der original-code suggeriert aber, dass alles hinter dem ersten else ein zusammengehöriger block ist, also sich dass 'innere' else nur auf das if direkt davor bezieht.
    🙂



  • ~fricky schrieb:

    Jester schrieb:

    ~fricky schrieb:

    ^^du hast recht, es ist falsch eingerückt und ich bin voll drauf reingefallen.

    Was heißt hier falsch eingerückt.

    der original-code suggeriert aber, dass alles hinter dem ersten else ein zusammengehöriger block ist, also sich dass 'innere' else nur auf das if direkt davor bezieht.
    🙂

    Überraschung: genau so ist es auch. Es gibt kein separates else-if-Konstrukt in C++ -- braucht man ja auch nicht. Mal Dir doch einfach mal den entsprechenden Parse-Baum auf.



  • es gibt aber sowas:

    if (...)
    {
     ...
    }
    else if (...)
    {
     ...
    }
    else if (...)
    {
     ...
    }
    else
    {
     ...
    }
    

    und verschachtelte konstrukte, wie z.b. das hier:

    if (...)
    {
      if (...)
      {
       ...
      }
      else 
      {
       ...
      }
    }
    else 
    {
      if (...)
      {
       ...
      }
      else 
      {
       ...
      }
    }
    

    nach der irreführenden einrückung von pc() sieht's aus wie ein verschachteltes if...else{if...else}, was es aber in wirklichkeit nicht ist. deswegen ist die einrückung von abc.w besser (auch ohne klammern).
    🙂



  • ~fricky schrieb:

    nach der irreführenden einrückung von pc() sieht's aus wie ein verschachteltes if...else{if...else}, was es aber in wirklichkeit nicht ist.

    Das versuche ich doch die ganze Zeit zu erklären, es *ist* in Wirklichkeit (nämlich so wie es die Grammatik definiert und der Parser parst) ein verschachteltes if ... else {if ... else ...}.

    Die Regel für das if sieht in etwa so aus:
    statement -> if (bedingung) statement [else statement]

    Das nachfolgende zweite if gehört syntaktisch zu dem statement im else-Zweig.

    Hier kann man sich's auch anschauen: http://linuxsoftware.co.nz/cppgrammar.html#selection-statement



  • *schluck*, du hast recht! da programmiert man schon jahrelang in C und hat ein völlig falsches bild von einfachen if/else konstrukten (das dazu noch funktioniert?!).
    🙂



  • Huiui! Hätte nicht gedacht, einen Glaubenskrieg ums Indenting auszulösen 😉 . Aber mir erschien das damals einfach so logisch, weil's wirklich geschachtelt ist. Es gibt ja auch kein "else do" oder "else for", weshalb sollte ich genau dem "if" die Einrückung verweigern 😕 ?
    Ist übrigens auch der Default meines Lieblingseditors.
    😃



  • pointercrash() schrieb:

    Huiui! Hätte nicht gedacht, einen Glaubenskrieg ums Indenting auszulösen 😉 . Aber mir erschien das damals einfach so logisch, weil's wirklich geschachtelt ist. Es gibt ja auch kein "else do" oder "else for", weshalb sollte ich genau dem "if" die Einrückung verweigern 😕 ?
    Ist übrigens auch der Default meines Lieblingseditors.
    😃

    Das ist doch kein Glaubenskrieg. Wir haben uns eigentlich mit einer rein fachlichen Fragestellung auseinandergesetzt. Ich sagte ja, ich würde es auch nicht einrücken. Ich habe nur der Behauptung die Einrückung sei falsch widersprochen.

    Ein Grund warum man auf die Einrückung verzichten könnte, ist dass es sich semantisch eigentlich um drei gleichberechtigte Fälle handelt: es wird genau einer davon angesprochen. Das kommt ohne Einrückung imo deutlicher raus.



  • Jester schrieb:

    Ein Grund warum man auf die Einrückung verzichten könnte, ist dass es sich semantisch eigentlich um drei gleichberechtigte Fälle handelt: es wird genau einer davon angesprochen. Das kommt ohne Einrückung imo deutlicher raus.

    Jetzt bin ich mir nicht sicher, ob wir wirklich das Gleiche meinen. Logisch betrachtet kommt nur einer der drei Fälle dran, aber ganz gleichberechtigt sind sie ja nicht:

    if ((abs_x >= abs_y) && (abs_x >= abs_z))
    		leader = 'x';
    	else
    		if (abs_y >= abs_z)
    			leader = 'y';
    		else
    			leader = 'z';
    

    Dadurch wird der Erkennung x->y->z der Vorrang gegeben, auch wenn Gleichheiten bestehen. Erst wenn x nicht größergleich als y bzw. z, wird weitergeprüft. Die Prüfung y gegen z setzt schon voraus, daß x nicht der Größte ist und bevorzugt bei Gleichheit y.
    Hatte den Grund, daß der abspulende Automat, der zunächst schauen mußte, ob x oder y oder z fahren in der gleichen Reihenfolge geparst hat, dadurch meist um eine knappe µs Vergleichszeit sparen konnte. Hat sich aber bei mir auch schon überholt, ich mache das mittlerweile Funktionspointergefädelt.

    Das als "else if"- Kette hinzuschreiben macht meines Erachtens dann Sinn, wenn man rechts knapp mit dem Platz dran ist und zehn Abfragen vorhat - in Abhängigkeit vom Nichtzutreffen der jeweils vorherigen Abfragen.
    Für echt gleichberechtigte Abfragen gibt es ja "switch - case" (vom "break"- Weglassen mal abgesehen).

    if - else- Konstrukte sind durch ihre Schachtelung per se hierarchisch, was hier ein durchaus erwünschter Effekt war. 😉



  • pointercrash() schrieb:

    ...Für echt gleichberechtigte Abfragen gibt es ja "switch - case" (vom "break"- Weglassen mal abgesehen)...

    Was meinst Du mit "break" weglassen? Etwa so:

    switch (a)
    {
        if (c == d) case e: ...;
        else case d: ...;
        if (0) default: ...;
    }
    

    Das geht auch und man kann es beliebig kompliziert machen 🕶

    PS: Ist nur ein dummer Vorschlag von mir. Auf keinen Fall nachmachen... 🙂



  • pointercrash() schrieb:

    Für echt gleichberechtigte Abfragen gibt es ja "switch - case" (vom "break"- Weglassen mal abgesehen).

    Das funktioniert aber nicht immer. Schließlich lässt sich nicht jede Bedingung ohne Umwege auf einen einzelnen Vergleich mit == runterbrechen.

    Meiner Meinung nach sind Deine drei Fälle schon gleichberechtigt. Dass Du in Randfällen einen bestimmten vorziehst tut der Sache imo keinen Abbruch.



  • abc.w schrieb:

    Auf keinen Fall nachmachen... 🙂

    Mein' ich auch. Aber z.B. bei solchen Sachen:

    switch (cc)
    	{
    	case 'i':		// i = inch
    		var *= 25.4;
    	case 'm':		// m = mm
    		u = var * var;
    	break;
    	case 'T':
    		{
    			foo();
    		}
    	}
    

    Da machen 'i' und 'm' das Identische, nur, daß 'i' vorher "var" von inch auf metrisch mm umrechnet.

    Jester schrieb:

    Das funktioniert aber nicht immer. Schließlich lässt sich nicht jede Bedingung ohne Umwege auf einen einzelnen Vergleich mit == runterbrechen.

    Meiner Meinung nach sind Deine drei Fälle schon gleichberechtigt. Dass Du in Randfällen einen bestimmten vorziehst tut der Sache imo keinen Abbruch.

    Wie man's nimmt, solange dabei nicht vergessen wird, daß doch Abhängigkeiten bestehen. Bei ein, zwei Teilnehmern bleibt das trivial, aber bastel' mal 6 Entscheidungsteilnehmer in eine 4- Stufige if- then - else -if ein.
    Ich denke, wir gehen darin überein, daß es lesbarere Formulierungen geben muß, was? 😉

    EDIT: hustbaer-Entnörgel-Edit.



  • [nörgel-mode]

    case :'i'
    

    ich glaube nicht dass sich das compilieren lässt
    [/nörgel-mode]



  • hustbaer schrieb:

    [nörgel-mode]

    case :'i'
    

    ich glaube nicht dass sich das compilieren lässt
    [/nörgel-mode]

    Peinlich, peinlich, Du hast ja so recht 🙄 . Immerhin hätten 'i' und 'm' immer noch das Gleiche gemacht: Nicht compiliert! 🤡


Anmelden zum Antworten