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