My float map library
fmap.cpp
- Committer:
- est2fe
- Date:
- 2010-12-09
- Revision:
- 0:1e9eea14a6b9
File content as of revision 0:1e9eea14a6b9:
#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