My float map library
Revision 0:1e9eea14a6b9, committed 2010-12-09
- Comitter:
- est2fe
- Date:
- Thu Dec 09 14:19:12 2010 +0000
- Commit message:
- 0.9.0
Changed in this revision
fmap.cpp | Show annotated file Show diff for this revision Revisions of this file |
fmap.h | Show annotated file Show diff for this revision Revisions of this file |
diff -r 000000000000 -r 1e9eea14a6b9 fmap.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/fmap.cpp Thu Dec 09 14:19:12 2010 +0000 @@ -0,0 +1,209 @@ +#ifndef __map_c__ +#define __map_c__ + +#include "fmap.h" +#include <math.h> +#include <stdlib.h> +#include <string.h> + +int find_x_Bereich (float x, fmap_s *map) + { + // return -3 -> Tabelle ist ungültig, Anzahl Stützstellen ist negativ + // return -2 -> Tabelle ist ungültig, Anzahl Stützstellen ist 0 + // return -1 -> map->kl = NULL + // + int max_i = map->groesse; // map.groesse + float *fz = 0x00; + if (max_i < 0) + { + return -3; + } else { } + switch (max_i) + { + case 0: + { + return -2; + //break; + } + case 1: + { + // Es ist nur ein Y-Wert vorhanden + return 0; // y1 zurückgeben + //break; + } + case 2: + { + // Kennlinie mit 2 Stützstellen -> den unteren X-Wert zurückgeben + return 0; // Es ist nur eine Kennlinie und keine Kurve + //break; + } + default: + { + // Anzahl Stützstellen > 2 -> X-Bereich suchen + int i = 0; + fz = map->kl; + if (fz == 0) { return -1; } else { } + if (x <= *fz) + { + // Wenn der X-Wert kleiner als die untere Stützstelle ist, Index = 0 + return 0; + } else { } + while ((x >= *fz) && (i < (max_i - 1))) + { + i++; + fz +=2; // +; fz++; // Jede 2. Float ist eine Stützstelle (x-Wert) + } + return --i; + //break; + } + } + // Da kommen im Regelfall eigentlich nie an! + // Trotzdem abfangen, falls i < 0 gewesen waere! + //return -3; + } + +float calc_fix_map (float x, int i, fmap_s *map) + { + /* + ^ + y | / + | / + y2|------------------------------------------------------o + | / | + | / | + y |----------------------------o / | + | / | | + | / | | + y1|--------O m1 | | + b | _ / | | | + | m2 | | | + | | | | + ----------|-------------------|-------------------------|--------------> + x0 x1 x x2 x + + y = m*x + b + + m = dy / dx + + m = m1 = (y2 - y1) / (x2 - x1) + m2 = (y1 - b) / (x1 - 0) + + (y2-y1)/(x2-x1) = (y1-b)/x1 + x1((y2-y1)/(x2-x1)) = y1-b + b = y1 - x1((y2-y1)/(x2-x1)) + b = y1 - x1*m mit m = (y2-y1)/(x2-x1) + + y = mx + b + + mit m1 = m2 -> b = x1 - y1 / m (umstellen nach b) + + y = m*x + x1 - y1 / m und -> m != 0! -> dx != 0!!! + + */ + + // Mittels Geradengleichung den y-Wert ermitteln + // y = mx + b + // m = dy/dx + // return: NaN bei dx = 0 + // b = y [x = 0]; + // -> y = m*x + x1 - (y1 / m) und dx != 0 + + float *fz = 0x00; + + float x1; + float x2; + float y1; + float y2; + float dx; + float dy; + float b; + + fz = map->kl; + if (i < 0) { return *(fz + 1); } else { } // y1 zurückgeben + fz += 2 * i; + x1 = *fz++; + y1 = *fz++; + x2 = *fz++; + y2 = *fz; + + dx = x2 - x1; + dy = y2 - y1; + b = y1 - (x1 * (dy / dx)); + if (dx == 0) { return NAN; } else { } + if (dy == 0) { return y1; } else { } + // an den Bereichsgrenzen waagerecht begrenzen + if (x <= x1) { return y1; } else { } + if (x >= x2) { return y2; } else { } + + // und jetzt y = m * x + b mit b = y2 - (x1 / m) + // return m * x + b; + return ((x * dy/dx) + b); + } + +float calc_var_map (float x, fmap_s *map) + { + int i = find_x_Bereich (x, map); // i zeigt jetzt auf + if (i >= 0) + { + // return calc_fix_map (x, (map->kl)); // das zählt er evtl. 4 floats weiter + return calc_fix_map (x, i, map); // da zählt er evtl. 4 floats weiter + } + else + { + // ungültiger Index + return NAN; // oder doch 0.0 ? + } + } + +fmap_s *new_map (int groesse) + { + fmap_s *mz = (fmap_s *)malloc (sizeof (fmap_s)); + if (mz == 0x00) + { + return 0x00; + } + else + { + size_t gr = (2 * groesse) * sizeof (mz->kl); + mz->kl = (float *) malloc (gr); + if (mz->kl == NULL) + { + return 0; + } + else + { + memset (mz->kl, 0.0, gr); + } + } + mz->groesse = groesse; + return mz; + } + +void free_map (fmap_s *m) + { + free (m->kl); + free (m); + } + +int set_map_val (fmap_s *m, int index, float x, float y) + { + // return -2 -> Index negativ + // return -1 -> Index zu gross + // return 0 -> alles ok + if (index < 0) + { + return -2; + } else {} + if (index > m->groesse) + { + return -1; + } + else + { + *((m->kl) + (2 * index)) = x; + *((m->kl) + (2 * index) + 1) = y; + } + return 0; + } + +#endif
diff -r 000000000000 -r 1e9eea14a6b9 fmap.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/fmap.h Thu Dec 09 14:19:12 2010 +0000 @@ -0,0 +1,26 @@ +#ifndef __map_h__ +#define __map_h__ + +typedef struct fmap_s // Map mit variabler Stuetzstellenanzahl + { + /* + Struktur: + Anzahl Stuetzstellen > = 2 + float *Kennlinie; // wobei immer im Wechsel x1, y1, x2 y2, x3, y3, ... kommt + */ + int groesse; + float *kl; // Feld mit floats (mind. 2 Stück) + } fmap_s; + +//#define NAN -10000 + +fmap_s *new_map (int groesse); + +int find_x_Bereich (float x, fmap_s *map); +float calc_fix_map (float x, int i, fmap_s *map); +float calc_var_map (float x, fmap_s *map); +int set_map_val (fmap_s *m, int index, float x, float y); + +void free_map (fmap_s *m); + +#endif