00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
#ifndef INTERVALMAP_H
00022
#define INTERVALMAP_H
00023
00024
#include<vector>
00025
00026
#include "types.h"
00027
#include "function.h"
00028
#include "vector.h"
00029
00034 template <
class Interpol,
class Eval>
class IntervalMap {
00035
00036
public:
00039 IntervalMap(): data() {}
00040
00043 IntervalMap(
const IntervalMap& im): data() {
00044
for(
unsigned int i=0; i<im.
data.size(); ++i) {
00045 data.push_back(Entry(im.
data[i].value, im.
data[i].obj->copy() ));
00046 }
00047 }
00048
00049
virtual ~
IntervalMap() {
00050
00051
for(
unsigned int i=0; i<data.size(); ++i) {
00052
delete(data[i].obj);
00053 }
00054
00055 }
00056
00057
public:
00058
00061 void insert(FLT value,
const Interpol* obj) {
00062 Entry newentry = Entry(value,obj);
00063 data.push_back(newentry);
00064
int i = data.size()-1;
00065
while(i>0 && data[i].value<data[i-1].value) {
00066
00067
00068 data[i]=data[i-1];
00069 data[i-1]=newentry;
00070 i--;
00071 }
00072 }
00073
00074 Eval lookup(FLT value,
const Vector3& v)
const {
00075
00076
00077
int i = 0;
00078
int j = data.size()-1;
00079
00080
while(i<j-1) {
00081
int k = (i+j)/2;
00082
if ( data[k].value>value) {
00083 j = k;
00084 }
else {
00085 i = k;
00086 }
00087 }
00088
00089
00090
00091
00092
if (i==j)
return data[i].obj->evaluateAt(v);
00093
if (value<data[i].value)
return data[i].obj->evaluateAt(v);
00094
if (value>data[j].value)
return data[j].obj->evaluateAt(v);
00095
00096
00097
return linearInterpolate(i,j,value,v);
00098
00099 }
00100
00101
private:
00102
class Entry {
00103
public:
00104 FLT value;
00105
const Interpol* obj;
00106
public:
00107 Entry(FLT v,
const Interpol* o): value(v), obj(o) {};
00108 };
00109
00110
private:
00111 std::vector<Entry> data;
00112
00113
private:
00114 Eval linearInterpolate(
int a,
int b, FLT v,
const Vector3& point)
const {
00115 Eval tmp1 = data[a].obj->evaluateAt(point);
00116 Eval tmp2 = data[b].obj->evaluateAt(point);
00117 FLT va = data[a].value;
00118 FLT vb = data[b].value;
00119 tmp1.scale( (vb-v)/(vb-va) );
00120 tmp2.scale( (v-va)/(vb-va) );
00121 tmp1.add(tmp2);
00122
return tmp1;
00123 }
00124
00125 };
00126
00127
#endif