Source: raytracer/intervalmap.h


Annotated List
Files
Globals
Hierarchy
Index
/* *************************************************************************
                          intervalmap.h  -  description
                             -------------------
    begin                : Fri Oct 18 2002
    copyright            : (C) 2002 by Micha Riser
    email                : mriser@gmx.net
 ************************************************************************* */

/* *************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ************************************************************************* */

#ifndef INTERVALMAP_H
#define INTERVALMAP_H

#include <vector>
using std::vector;

#include "types.h"
#include "function.h"
#include "vector.h"

/**Template for interval maps. Orders some interpolatable object for each
  *value in given range. Eval class has to support 'add' and 'scale' method.
  *@author Micha Riser
  */
template <class Interpol, class Eval> class IntervalMap {

public: // Constructor and destructor
    /**Create empty interval map.
      */
    IntervalMap(): data() {}

    /**Copy constructor.
      */
    IntervalMap(const IntervalMap& im): data() {
        for(unsigned int i=0; i<im.data.size(); ++i) {
            data.push_back(Entry(im.data[i].value, im.data[i].obj->copy() ));
        }        
    }

    virtual ~IntervalMap() {

        for(unsigned int i=0; i<data.size(); ++i) {
            delete(data[i].obj);
        }
        
    }

public: // Public Methods

    /**Insert entry into interval map.
      */
    void insert(FLT value, const Interpol* obj) {
        Entry newentry = Entry(value,obj);
        data.push_back(newentry);
        int i = data.size()-1;
        while(i>0 && data[i].value<data[i-1].value) {
            // swap i and i-1
            // i is newentry
            data[i]=data[i-1];
            data[i-1]=newentry;
            i--;
        }
    }

    Eval lookup(FLT value, const Vector3& v) const { 

        // do binary search
        int i = 0;
        int j = data.size()-1;

        while(i<j-1) {
            int k = (i+j)/2;
            if ( data[k].value>value) {
                j = k;
            } else {
                i = k;
            }
        }

        // do interpolation

        // exepctional cases
        if (i==j) return data[i].obj->evaluateAt(v);
        if (value<data[i].value) return data[i].obj->evaluateAt(v);
        if (value>data[j].value) return data[j].obj->evaluateAt(v);

        // normal case
        return linearInterpolate(i,j,value,v);

    }

private: // Inner classes
    class Entry {
    public: // Public attributes
        FLT value; // DBL?
        const Interpol* obj;
    public: // Constructor and destructor
        Entry(FLT v, const Interpol* o): value(v), obj(o) {};
    };
        
private: // Private attributes
    vector<Entry> data;

private: // Private methods
    Eval linearInterpolate(int a, int b, FLT v, const Vector3& point) const {
        Eval tmp1 = data[a].obj->evaluateAt(point);
        Eval tmp2 = data[b].obj->evaluateAt(point);
        FLT va = data[a].value;
        FLT vb = data[b].value;
        tmp1.scale( (vb-v)/(vb-va) );
        tmp2.scale( (v-va)/(vb-va) );
        tmp1.add(tmp2);
        return tmp1;
    }

};

#endif

Generated by: micha@laptop on Thu Oct 24 20:25:24 2002, using kdoc 2.0a53.