My float map library

Revision:
0:1e9eea14a6b9
--- /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