Berechnung von Achsen-Schrittgrößen von Diagrammen
-
Hallo zusammen,
ich habe ein kleines Problem:
Ich habe eine Software geschrieben, die Diagramme für ein propietäres Anzeigeprogramm erzeugt. Dieses Diagrammformat erwartet Achsenangaben im Format:
XMin, XSchritt, XMax, YMin, YSchritt, YMaxIch möchte nun garantieren, daß die dargestellten Diagramme von Menschen leicht interpretiert werden können. Dazu ist es notwendig, eine "vernünftige" Aufteilung der Achse in 10 bis 12 Schritte zu gewährleisten.
Kurz: Bei YMax 0.156 sind die bisher erzeugten Achenschritte (0.0156, 0.0312, etc.) nicht "einfach" lesbar. Etwas wie "0.02, 0.04, 0.06, ..." wäre deutlich hilfreicher.
Nur: Wie bestimme ich die geeignetsten Achsen-Auflösungen? Hat vielleicht jemand ein ähnliches Problem schonmal gelöst, und wäre bereit, mir auszuhelfen?
Vielen Dank im Voraus.
Sid
-
0.156 ist natürlich nur ein Beispiel. Genauso gut könnte der Maximalwert bei 1934493 liegen - oder bei 0.03 - oder 0.9, ....
Ich habe zwar kein Problem damit, aus den Datensätzen von Hand eine vernünftige Schrittgröße auszuwählen - nur programmatisch kriege ich meine Vorgehensweise nicht übersetzt, weil mir "einfach klar ist", wie die Schrittgröße sein müsste. Raargh.
Gruss
Sid
-
Die Schrittweite kannst du relativ leicht über den dekadischen Logarithmus finden. Log10 -> Runden auf ganze Zahlen -> Log10 umkehren.
Eventuell kannst du noch prüfen , ob log10(2) oder log10(5) noch mit reinpasst (also zwischen den errechneten und den gerundeten Wert), dann kannst du Werte nehmen, die auf 2 oder 5 enden, wenn du sonst zu viele Teilschritte hast.
-
Danke, aber ich hätte eine Bitte:
Kannst du das bitte näher ausführen? Ich kann dir leider nicht ganz folgen.
Gruss
Sid
-
Hallo,
Was eine vernünftige Aufteilung darstellt ist natürlich Ansichtssache. Wenn man nur log(10) log(2) und log(5) nimmt, hätte man also Aufteilungen bei 0.1 0.2 0.5
Manche möchten noch 0.25 0.3 o.ä.
Dann könnte man einfach abfragen.
Bsp. in C++ (steps - Anzahl der Schritte)double CalcIntUpToValues(double Min, double Max, int steps) { double dmin = Min; double dmax = Max; double Diff = dmax - dmin; double lDiff; if( Diff > 0.0 ) lDiff = log10(Diff); else return; if( lDiff > 1.0 ) lDiff -= int(lDiff); if( lDiff < 0.0 ) lDiff = lDiff - int(lDiff) + 1.0; double DNeu = pow(10, lDiff); double Fakt = Diff / DNeu; double rstep = DNeu / steps; int itemp = dmin; if( dmin < 0.0 ) --itemp; double rest; if( dmin > 0 ) rest = dmin - itemp; else rest = fabs(itemp - dmin); if( rstep > 0.625 ) { rstep = 0.75 * Fakt; double div = rest / rstep; if( div < 1.0 ) dmin = itemp; else dmin = itemp + rstep * int(div); } else if( rstep > 0.45 ) { rstep = 0.5 * Fakt; double div = rest / rstep; if( div < 1.0 ) dmin = itemp; else dmin = itemp + rstep * int(div); } else if( rstep > 0.35 ) { rstep = 0.4 * Fakt; double div = rest / rstep; if( div < 1.0 ) dmin = itemp; else dmin = itemp + rstep * int(div); } else if( rstep > 0.275 ) { rstep = 0.3 * Fakt; double div = rest / rstep; if( div < 1.0 ) dmin = itemp; else dmin = itemp + rstep * int(div); } else if( rstep > 0.225 ) { rstep = 0.25 * Fakt; double div = rest / rstep; if( div < 1.0 ) dmin = itemp; else dmin = itemp + rstep * int(div); } else if( rstep > 0.175 ) { rstep = 0.2 * Fakt; double div = rest / rstep; if( div < 1.0 ) dmin = itemp; else dmin = itemp + rstep * int(div); } else if( rstep > 0.1375 ) { rstep = 0.15 * Fakt; double div = rest / rstep; if( div < 1.0 ) dmin = itemp; else dmin = itemp + rstep * int(div); } else if( rstep > 0.1125 ) { rstep = 0.125 * Fakt; double div = rest / rstep; if( div < 1.0 ) dmin = itemp; else dmin = itemp + rstep * int(div); } else { rstep = 0.1 * Fakt; double div = rest / rstep; if( div < 1.0 ) dmin = itemp; else dmin = itemp + rstep * int(div); } return rstep; } //---------------------------------------------------------------------------
Das kann man sicher noch vereinfachen.