Differenz zwischen Float-Variablen (Kreis)

Wichtiger Hinweis: Bitte ändert nicht manuell die Schriftfarbe auf schwarz sondern belasst es bei der Standardeinstellung. Somit tragt ihr dazu bei dass euer Text auch bei Verwendung unseren dunklen Forenstils noch lesbar ist!

Tipp: Ihr wollt längere Codeausschnitte oder Logfiles bereitstellen? Benutzt unseren eigenen PasteBin-Dienst Link
  • Hi,


    gibt es irgendwie einen besseren Weg zwei Grad-Variablen zu vergleichen und ihren Unterschied herauszubekommen?
    (man bedenke, dass ich nicht die normale Differenz, sondern eine Differenz, die beachtet, dass ein Kreis 360° hat.
    Es ist also unmöglich einen größerer Wert als 180 herauszubekommen.)


    Beispiele

    Beispiel 1:
    Zahl1: 25.5
    Zahl2: 38.6
    Unterschied: 13.1

    Beispiele
    Beispiel 2:
    Zahl1: 10.0
    Zahl2: 340.0
    Unterschied: 30.0

    Beispiele
    Beispiel 3:
    Zahl1: 10.0
    Zahl2: 189.0
    Unterschied: 179.0

    Beispiele
    Beispiel 4:
    Zahl1: 10.0
    Zahl2: 191.0
    Unterschied: 179.0


    Ich habs momentan so (funktioniert perfekt):
    stock Float:CalcDifference(Float:value1,Float:value2)
    {
    new Float:calc=floatabs((value1-value2));
    if(calc>180.0) return floatabs(calc-360.0);
    return calc;
    }


    Da ich diese Abfrage in einem Timer verwende, der mehrmals in der Sekunde aufgerufen wird,
    möchte ich diese Abfrage so gestalten, dass der Prozessor so wenig wie möglich rechnen muss.


    Die if-Abfrage und die beiden floatabs-Funktionsnutzungen stören mich da ein bisschen.
    Außerdem würde ich das lieber direkt machen, ohne eine Extra-Funktion aufzurufen.



    Gibt es da eine intelligentere / schönere / elegantere Lösung?



    Danke für eure Antworten! :)

    Einmal editiert, zuletzt von Pille ()

  • Ob man das mit Floats in samp so machen kann, das weiß ich nicht.
    #define CalcDifference(%0,%1)if(floatabs((%0-%1))>180.0)return floatabs((%0-%1))-360.0;


    Vielleicht kann mir ein "Profi" das bestätigen bzw. sagen ob das funktionieren würde.

  • Vielleicht kann mir ein "Profi" das bestätigen bzw. sagen ob das funktionieren würde.


    Das Makro was du geschrieben hast, würde nicht den Sinn und Zweck erfüllen, den er haben möchte :D


    CalDifference würde bei dir mit der if Abfrage und dem Return ersetzt werden, aber er will ja den Wert haben und nicht das return bzw die if-Abfrage...


    Also so könnte er es machen:


    #define CalcDifference(%0,%1) ((%0-%1) > 180) ? floatabs((%0-%1) - 360.0) : (%0-%1)


    mfg. :thumbup:

    ast2ufdyxkb1.png


    Leute, lernt scripten und versucht mal lieber etwas selber zu schreiben, als es aus einem GF zu kopieren. :S

  • Könntest du mir noch erklären, was genau der Code macht?


    Er macht genau das, was deine Funktion auch macht ^^


    Das mit ? und : ist der sog ternary Operator, das ist nichts anderes als eine if und else abfrage.


    new test = 5;


    if(test == 5) print("Test ist 5!");
    else print("Test ist nicht 5!");


    //Und das kann man halt auch anders darstellen
    new test = 5;


    print((test == 5) ? ("Test ist 5!") : ("Test ist nicht 5!"));


    Er ist halt kürzer und schneller ;)


    mfg. :thumbup:


    //Edit: Damit der Code auch funtkioniert ^^

    ast2ufdyxkb1.png


    Leute, lernt scripten und versucht mal lieber etwas selber zu schreiben, als es aus einem GF zu kopieren. :S

  • Da hast du wohl ein Denkfehler drin.


    Eh nein? :huh:


    Achso, grad gesehen du hast ja bei beiden den absoluten Wert...dann schreibs so:


    #define CalcDifference(%0,%1) ((%0-%1) > 180) ? floatabs((%0-%1) - 360.0) : floatabs(%0-%1)


    mfg. :thumbup:

    ast2ufdyxkb1.png


    Leute, lernt scripten und versucht mal lieber etwas selber zu schreiben, als es aus einem GF zu kopieren. :S

  • Du musst wegen mir nicht den absoluten Wert überall einsetzen,
    nur wenn er unbedingt nötig ist natürlich ^^


    #define CalcDifference(%0,%1) ((%0-%1) > 180) ? floatabs((%0-%1) - 360.0) : floatabs(%0-%1)


    Hier die erste Abfrage ist ja schon fehlerhaft, weil man nicht den absoluten Wert nimmt, oder?



    Beispiel:
    Zahl1: 10
    Zahl2: 200


    Du würdest am Anfang vergleichen:


    ((10-200)>180) ? ... : floatabs(10-200)


    Als Endergebnis käme 190 raus.. und das möchte ich ja nicht. ^^





    So würde es funktionieren:
    (floatabs(%0-%1) > 180) ? floatabs(floatabs(%0-%1) - 360.0) : floatabs(%0-%1)


    Allerdings wird bei jeder Abfrage 2x den absoluten Wert berechnet und 2x die Zahlen voneinander subtrahiert.
    Ist nicht ganz im Sinne des Erfinders, verstehste? :D

  • //Edit: Achso jetzt weiß ich was du meinst :rolleyes:


    Hier, schreibs mal so, dann geht es am schnellsten:


    #define f_Get(%0,%1) ((%0-%1) < 0 ? (%0-%1)*-1.0 : (%0-%1))
    #define CalcDifference(%0,%1) (f_Get(%0,%1) > 180) ? f_Get(f_Get(%0,%1),360.0) : f_Get(%0,%1)


    mfg. :thumbup:

    ast2ufdyxkb1.png


    Leute, lernt scripten und versucht mal lieber etwas selber zu schreiben, als es aus einem GF zu kopieren. :S

    Einmal editiert, zuletzt von Kaliber ()

  • Wieso nicht?!


    Weil ich die Differen der beiden Zahlen berechnen möchte.
    Da ich weiß, dass ein Kreis 360° hat, kann ich nie mehr als 180° von einem Punkt entfernt sein.


    Stells dir vor wie in einem Karusell, wo ich an der Umrisslinie entlang zu einem anderen Punkt auf der Umrisslinie laufen muss.
    Egal wo der ist.. der Weg von meinem Punkt (bzw. meiner Gradanzahl) zu dem anderen (bzw. zu der Gradanzahl) kann nicht
    größer als 180 sein.

  • do.de - Domain-Offensive - Domains für alle und zu super Preisen
  • Weil ich die Differen der beiden Zahlen berechnen möchte.
    Da ich weiß, dass ein Kreis 360° hat, kann ich nie mehr als 180° von einem Punkt entfernt sein.


    Stells dir vor wie in einem Karusell, wo ich an der Umrisslinie entlang zu einem anderen Punkt auf der Umrisslinie laufen muss.
    Egal wo der ist.. der Weg von meinem Punkt (bzw. meiner Gradanzahl) zu dem anderen (bzw. zu der Gradanzahl) kann nicht
    größer als 180 sein.


    Ja...habs an deinem Beispiel schon gesehen, schau dir den Code an:


    #define f_Get(%0,%1) ((%0-%1) < 0 ? (%0-%1)*-1.0 : (%0-%1))
    #define CalcDifference(%0,%1) (f_Get(%0,%1) > 180) ? f_Get(f_Get(%0,%1),360.0) : f_Get(%0,%1)


    mfg. :thumbup:

    ast2ufdyxkb1.png


    Leute, lernt scripten und versucht mal lieber etwas selber zu schreiben, als es aus einem GF zu kopieren. :S

  • Ja, funktioniert, allerdings nicht besonders ressourcenschonend.
    Diese zwei verschachtelten Defines brauchen im Gegensatz zu der normalen Funktion dann doch relativ lange..
    Selbst dein erster Versuch ist noch langsamer ^^


    Danke für die Mühe, Kaliber, aber das ist es noch nicht was ich suche.


    Vielleicht gibt es ja keine Möglichkeit das besser hinzukriegen als ganz o.g.?

  • Selbst dein erster Versuch ist noch langsamer


    Ja sehe es auch gerade, halt einfach weil ich das nirgends Zwischenspeicher, sondern immer wieder neu berechne...


    Nun, das hier ist dann schon echt die schnellste Version:


    stock Float:CalcDifference(Float:v1,Float:v2) {
    new Float:calc = floatabs(v1-v2);
    return (calc > 180.0) ? floatabs(calc-360.0) : calc;
    }


    Und ich sag mal so, für 10.000 Durchläufe, braucht die Funktion 4ms...das ist schnell genug ;)


    mfg. :thumbup:

    ast2ufdyxkb1.png


    Leute, lernt scripten und versucht mal lieber etwas selber zu schreiben, als es aus einem GF zu kopieren. :S