Пример #1
0
tgt::vec3 Flow3D::lookupFlowTrilinear(const tgt::vec3& r) const {
    tgt::ivec3 ir1(static_cast<int>(floorf(r.x)), static_cast<int>(floorf(r.y)),
        static_cast<int>(floorf(r.z)));
    ir1 = clampToFlowDimensions(ir1);
    tgt::ivec3 ir2 = clampToFlowDimensions(ir1 + tgt::ivec3(1));

    // interpolate in x-direction
    //
    tgt::vec3 v1 = linearInterpolation(r.x, ir1, 0);
    tgt::vec3 v2 = linearInterpolation(r.x, tgt::ivec3(0, ir2.y, ir1.z), 0);
    tgt::vec3 v3 = linearInterpolation(r.x, tgt::ivec3(0, ir1.y, ir2.z), 0);
    tgt::vec3 v4 = linearInterpolation(r.x, ir2, 0);

    // interpolates value from x-direction interpolation in y-direction
    //
    float fintegral = 0.0f;
    float b = modff(r.y, &fintegral);
    float a = 1.0f - b;
    tgt::vec3 v5 = ((v1 * a) + (v2 * b));
    tgt::vec3 v6 = ((v3 * a) + (v4 * b));

    // interpolate values from y-direction interpolation in z-drection
    //
    b = modff(r.z, &fintegral);
    a = 1.0f - b;
    return ((v5 * a) + (v6 * b));
}
Пример #2
0
//Gouraud shading, uses linear interpolation to determine the color
int Graph::drawLine( Point p1, Point p2){ // should have named it scanLine, as I only use this function for horizontal line drawing
  if(p1.x == p2.x){ //vertical line
    int y,y_end; 
    if(p1.y <= p2.y){
      y = p1.y;
      y_end = p2.y;
    }else{
      y = p2.y;
      y_end = p1.y;
    }
    for(; y<=y_end; y++)
      drawPixel(p1.x, y, linearInterpolation(y, p1.y, p2.y, p1.normalizedIntensity, p2.normalizedIntensity) ); 
    return 0;
  }
  else if(p1.y == p2.y){ // horizontal line
    int x, x_end;
    if(p1.x <= p2.x){
      x = p1.x;
      x_end =  p2.x;
    }
    else{
      x = p2.x;
      x_end = p1.x; 
    }
    for(; x <= x_end; x++)
      drawPixel(x, p1.y, linearInterpolation(x, p1.x, p2.x, p1.normalizedIntensity, p2.normalizedIntensity) );
    return 0;
  }
  DPRINT("################################################SLANTED LINE\n");
  bresenham(p1, p2);
  return 0;
}
Пример #3
0
void GraphData::render( ImageObject& img, const Rect& r )
{
	int pixel = 0;
	int old_pixel = 0;

	for(int i = 0; i < values-1; i++)
	{
		if(pInterpolation == GRAPH_INTERPOLATION_NONE)
		{
			img.putPixel(data_pixels[i][0], (int)getValue(i, 1), lineColor);
		}
		else
		{
			int spacing = (data_pixels[i+1][0]-data_pixels[i][0]);
			for(int i2 = 0; i2 < spacing; i2++)
			{
				float pos = ((float)i2/(float)(data_pixels[i+1][0]-data_pixels[i][0]));

				//TODO: Select interpolation type
				if(pInterpolation == GRAPH_INTERPOLATION_SPLINE)
				{
					pixel = (int)splineInterpolation(pos, getValue(i-2,1), getValue(i-1, 1), getValue(i, 1), getValue(i+1, 1), getValue(i+2, 1), getValue(i+3, 1));
				}
				else if(pInterpolation == GRAPH_INTERPOLATION_CUBIC)
				{
					pixel = (int)linearInterpolation(pos, getValue(i, 1), getValue(i+1, 1)) + 10;
				}
				else
				{
					pixel = (int)linearInterpolation(pos, getValue(i, 1), getValue(i+1, 1));
				}

				// Going up
				if(pixel > old_pixel)
				{
					for(int apa = abs(pixel-old_pixel); apa >= 0; apa--)
					{
						img.putPixel(data_pixels[i][0]+i2, pixel-apa, lineColor);
					}
				}
				// Going down
				else if(old_pixel > pixel)
				{
					for(int apa = abs(pixel-old_pixel); apa >= 0; apa--)
					{
						img.putPixel(data_pixels[i][0]+i2, pixel+apa-1, lineColor);
					}
				}
				// Same value as previous sample
				else
				{
					img.putPixel(data_pixels[i][0]+i2, pixel, lineColor);
					img.putPixel(data_pixels[i][0]+i2, pixel-1, lineColor);
				}
				old_pixel = pixel;
			}
		}
	}
}
Пример #4
0
    double MiscibilityLiveOil::miscible_oil(double press, const surfvol_t& surfvol,
					    int item, bool deriv) const
    {
	int section;
	double R = linearInterpolation(saturated_oil_table_[0],
					     saturated_oil_table_[3],
					     press, section);
	double maxR = (surfvol[Liquid] == 0.0) ? 0.0 : surfvol[Vapour]/surfvol[Liquid];
	if (deriv) {
	    if (R < maxR ) {  // Saturated case
		return linearInterpolationDerivative(saturated_oil_table_[0],
						saturated_oil_table_[item],
						press);
	    } else {  // Undersaturated case
		int is = tableIndex(saturated_oil_table_[3], maxR);
		double w = (maxR - saturated_oil_table_[3][is]) /
		    (saturated_oil_table_[3][is+1] - saturated_oil_table_[3][is]);
                ASSERT(undersat_oil_tables_[is][0].size() >= 2);
                ASSERT(undersat_oil_tables_[is+1][0].size() >= 2);
		double val1 =
		    linearInterpolationDerivative(undersat_oil_tables_[is][0],
					     undersat_oil_tables_[is][item],
					     press);
		double val2 = 
		    linearInterpolationDerivative(undersat_oil_tables_[is+1][0],
					     undersat_oil_tables_[is+1][item],
					     press);
		double val = val1 + w*(val2 - val1);
		return val;
	    }
	} else {
	    if (R < maxR ) {  // Saturated case
		return linearInterpolation(saturated_oil_table_[0],
						 saturated_oil_table_[item],
						 press);
	    } else {  // Undersaturated case
		// Interpolate between table sections
                int is = tableIndex(saturated_oil_table_[3], maxR);
		double w = (maxR - saturated_oil_table_[3][is]) /
		    (saturated_oil_table_[3][is+1] - saturated_oil_table_[3][is]);
                ASSERT(undersat_oil_tables_[is][0].size() >= 2);
                ASSERT(undersat_oil_tables_[is+1][0].size() >= 2);
		double val1 =
		    linearInterpolation(undersat_oil_tables_[is][0],
					      undersat_oil_tables_[is][item],
					      press);
		double val2 = 
		    linearInterpolation(undersat_oil_tables_[is+1][0],
					      undersat_oil_tables_[is+1][item],
					      press);
		double val = val1 + w*(val2 - val1);
		return val;
	    }
	}
    }
Пример #5
0
//------------------------------------------------------------------------------
f32 biLinearInterpolationSmooth(
	const f32 x0y0, const f32 x1y0,
	const f32 x0y1, const f32 x1y1,
	const f32 x, const f32 y)
{
	const f32 tx = smoothCurve(x);
	const f32 ty = smoothCurve(y);

	const f32 u = linearInterpolation(x0y0,x1y0, tx);
	const f32 v = linearInterpolation(x0y1,x1y1, tx);

	return linearInterpolation(u,v,ty);
}
Пример #6
0
float FETurbulence::noise2D(int channel, PaintingData& paintingData, const FloatPoint& noiseVector)
{
    struct Noise {
        int noisePositionIntegerValue;
        float noisePositionFractionValue;

        Noise(float component)
        {
            float position = component + s_perlinNoise;
            noisePositionIntegerValue = static_cast<int>(position);
            noisePositionFractionValue = position - noisePositionIntegerValue;
        }
    };

    Noise noiseX(noiseVector.x());
    Noise noiseY(noiseVector.y());
    float* q;
    float sx, sy, a, b, u, v;

    // If stitching, adjust lattice points accordingly.
    if (m_stitchTiles) {
        checkNoise(noiseX.noisePositionIntegerValue, paintingData.wrapX, paintingData.width);
        checkNoise(noiseY.noisePositionIntegerValue, paintingData.wrapY, paintingData.height);
    }

    noiseX.noisePositionIntegerValue &= s_blockMask;
    noiseY.noisePositionIntegerValue &= s_blockMask;
    int latticeIndex = paintingData.latticeSelector[noiseX.noisePositionIntegerValue];
    int nextLatticeIndex = paintingData.latticeSelector[(noiseX.noisePositionIntegerValue + 1) & s_blockMask];

    sx = smoothCurve(noiseX.noisePositionFractionValue);
    sy = smoothCurve(noiseY.noisePositionFractionValue);

    // This is taken 1:1 from SVG spec: http://www.w3.org/TR/SVG11/filters.html#feTurbulenceElement.
    int temp = paintingData.latticeSelector[latticeIndex + noiseY.noisePositionIntegerValue];
    q = paintingData.gradient[channel][temp];
    u = noiseX.noisePositionFractionValue * q[0] + noiseY.noisePositionFractionValue * q[1];
    temp = paintingData.latticeSelector[nextLatticeIndex + noiseY.noisePositionIntegerValue];
    q = paintingData.gradient[channel][temp];
    v = (noiseX.noisePositionFractionValue - 1) * q[0] + noiseY.noisePositionFractionValue * q[1];
    a = linearInterpolation(sx, u, v);
    temp = paintingData.latticeSelector[latticeIndex + noiseY.noisePositionIntegerValue + 1];
    q = paintingData.gradient[channel][temp];
    u = noiseX.noisePositionFractionValue * q[0] + (noiseY.noisePositionFractionValue - 1) * q[1];
    temp = paintingData.latticeSelector[nextLatticeIndex + noiseY.noisePositionIntegerValue + 1];
    q = paintingData.gradient[channel][temp];
    v = (noiseX.noisePositionFractionValue - 1) * q[0] + (noiseY.noisePositionFractionValue - 1) * q[1];
    b = linearInterpolation(sx, u, v);
    return linearInterpolation(sy, a, b);
}
Пример #7
0
int Graph::bresenham(Point pt1, Point pt2 ){ //overloaded bresenham, each points has its own color
  Point p1 = pt1;
  Point p2 = pt2;
  int x, y, x_end, y_end, p; 
  int dx = (p2.x - p1.x), dy = (p2.y - p1.y); //for determining sign of slope
  bool steep = false;
  float m = (float)dy/(float)dx ; //find the slope first
  DPRINT("The slope is %.2f\n", m);
  bool positive_slope;
  if( m >= 0 )  // positive slope
    positive_slope = true;
  else
    positive_slope = false;
  
  if( fabs(m) <= 1 ){ //shallow
    steep = false; 
  }
  else{ //steep
   steep = true;
   swapXY(&p1);
   swapXY(&p2);
  }
  determineStartAndEndPoints(p1, p2, &x, &y, &x_end, &y_end);
  //DPRINT("x: %d,\ty: %d,\tx_end: %d,\ty_end:%d\n", x, y, x_end, y_end);
  dx = abs(x_end - x);
  dy = abs(y_end - y);
  //draw first point  
  if(steep)
    drawPixel(y,x, linearInterpolation(x, p1.x, p2.x, p1.normalizedIntensity, p2.normalizedIntensity ) );//x and y was swapped before
  else 
    drawPixel(x,y, linearInterpolation(y, p1.y, p2.y, p1.normalizedIntensity, p2.normalizedIntensity ) );

  p = 2 * dy - dx;
  for( ; x < x_end; ){
    x++;
    if( p >= 0){ // if d1 - d2  >= 0, means d2 is shorter, so advance y one level up
        positive_slope? y++:y--; 
        p = p + 2*dy - 2*dx;
    }
    else // if d1 - d2 < 0; means d1 is shorter, so no change of y;
      p = p + 2*dy;
    
    if(steep)
      drawPixel(y,x, linearInterpolation(x, p1.x, p2.x, p1.normalizedIntensity, p2.normalizedIntensity ) );//x and y was swapped before
    else 
      drawPixel(x,y, linearInterpolation(y, p1.y, p2.y, p1.normalizedIntensity, p2.normalizedIntensity ) );
  }

  return 0;
}
Пример #8
0
void  testInterpolation(){

 double *fx, **a, *x;
 int dims=2;

 x=allocateDoubleVector(dims);
 a=allocateDoubleMatrix(dims,2);
 fx=allocateDoubleVector(dims*2);
 
 x[0]=0.25;
 x[1]=0.4;

 a[0][0]=0;
 a[0][1]=1;
 a[1][0]=0;
 a[1][1]=1;

 fx[0]=1;
 fx[1]=3;
 fx[2]=2;
 fx[3]=4;
 
 printf("\nInterpolation\n");
 printf("%f\n",linearInterpolation(fx, a, x, dims));

} 
Пример #9
0
qreal SprayBrush::rotationAngle(KisRandomSourceSP randomSource)
{
    qreal rotation = 0.0;

    if (m_shapeDynamicsProperties->fixedRotation) {
        rotation = deg2rad(m_shapeDynamicsProperties->fixedAngle);
    }

    if (m_shapeDynamicsProperties->randomRotation) {

        qreal randomValue = 0.0;

        if (m_properties->gaussian) {
            randomValue = qBound<qreal>(0.0, randomSource->generateGaussian(0.0, 0.5), 1.0);
        } else {
            randomValue = randomSource->generateNormalized();
        }

        rotation =
            linearInterpolation(rotation ,
                                M_PI * 2.0 * randomValue,
                                m_shapeDynamicsProperties->randomRotationWeight);
    }

    return rotation;
}
Пример #10
0
	inline double
	NonuniformTableLinear<T>
	::inverse(const double y) const
	{
            if (y_values_.front() < y_values_.back()) {
                return linearInterpolation(y_values_, x_values_, y);
            } else {
                if (y_values_reversed_.empty()) {
                    y_values_reversed_ = y_values_;
                    std::reverse(y_values_reversed_.begin(), y_values_reversed_.end());
                    ASSERT(isNondecreasing(y_values_reversed_.begin(), y_values_reversed_.end()));
                    x_values_reversed_ = x_values_;
                    std::reverse(x_values_reversed_.begin(), x_values_reversed_.end());
                }
                return linearInterpolation(y_values_reversed_, x_values_reversed_, y);
            }
	}
Пример #11
0
    T interpolatedNoise3D(const T x, const T y, const T z)
    {
        int integerX = static_cast<int>(x);
        int integerY = static_cast<int>(y);
        int integerZ = static_cast<int>(z);

        T fractionalX = x - integerX;
        T fractionalY = y - integerY;
        T fractionalZ = z - integerZ;

        T v1 = smoothNoise3D(integerX, integerY, integerZ);
        T v2 = smoothNoise3D(integerX + 1, integerY, integerZ);
        T v3 = smoothNoise3D(integerX, integerY + 1, integerZ);
        T v4 = smoothNoise3D(integerX + 1, integerY + 1, integerZ);
        T v5 = smoothNoise3D(integerX, integerY, integerZ + 1);
        T v6 = smoothNoise3D(integerX + 1, integerY, integerZ + 1);
        T v7 = smoothNoise3D(integerX, integerY + 1, integerZ + 1);
        T v8 = smoothNoise3D(integerX + 1, integerY + 1, integerZ + 1);

		T i1 = linearInterpolation(v1, v2, fractionalX);
        T i2 = linearInterpolation(v3, v4, fractionalX);
        T i3 = linearInterpolation(v5, v6, fractionalX);
        T i4 = linearInterpolation(v7, v8, fractionalX);

		T lvl0 = linearInterpolation(i1, i2, fractionalY);
        T lvl1 = linearInterpolation(i3, i4, fractionalY);

        return linearInterpolation(lvl0, lvl1, fractionalZ);
    }
Пример #12
0
	T interpolatedNoise2D(const T x, const T y)
	{
		int integerX = static_cast<int>(x);
		T fractionalX = x - integerX;
		
		int integerY = static_cast<int>(y);
		T fractionalY = y - integerY;

		T v1 = smoothedNoise2D(integerX, integerY);
		T v2 = smoothedNoise2D(integerX + 1, integerY);
		T v3 = smoothedNoise2D(integerX, integerY + 1);
		T v4 = smoothedNoise2D(integerX + 1, integerY + 1);

		T i1 = linearInterpolation(v1, v2, fractionalX);
		T i2 = linearInterpolation(v3, v4, fractionalX);
		
		return linearInterpolation(i1 , i2 , fractionalY);
	}
Пример #13
0
	T interpolatedNoise1D(const T x)
	{
		int integerX = static_cast<int>(x);
		T fractionalX = x - integerX;

		T v1 = smoothedNoise1D(integerX);
		T v2 = smoothedNoise1D(integerX + 1);

		return linearInterpolation(v1,v2,fractionalX);
	}
Пример #14
0
void EPtomo2010subMod(int xInd, int yInd, int zInd, globalDataValues *globalValues, gridStruct *location, depInterpVals *EPtomoData)
/*
 Purpose:   calculate the rho vp and vs values at a single lat long point for all the depths within this velocity submodel
 
 Input variables:
 depths         - pointer to a struct containing the references to which points lie within this velocity sub-model layer
 veloSubModNum  - the reference number of this velocity sub-model
 xInd           - the indice of the longitude point
 yInd           - the indice of the latitude point
 EPtomoData     - pointer to the Eberhart-Phillips 2010 tomography data
 
 Output variables:
 values         - struct containing the vp vs and rho values for all points within this velo sub-model
 
 */
{
    int count = 0;
    double p1, p2;
    double Rho1, Rho2, Vp1, Vp2, Vs1, Vs2;
    
    // find the indice of the first "surface" above the data point in question
    while(location->Z[zInd]<EPtomoData->deps[count]*1000)
    {
        count += 1;
    }
    
    // loop over the depth points and obtain the vp vs and rho values using interpolation between "surfaces"

    p1 = EPtomoData->deps[count-1]*1000;
    p2 = EPtomoData->deps[count]*1000;
    Rho1 = EPtomoData->Rho[count-1][xInd][yInd];
    Rho2 = EPtomoData->Rho[count][xInd][yInd];
    Vs1 = EPtomoData->Vs[count-1][xInd][yInd];
    Vs2 = EPtomoData->Vs[count][xInd][yInd];
    Vp1 = EPtomoData->Vp[count-1][xInd][yInd];
    Vp2 = EPtomoData->Vp[count][xInd][yInd];
    
    globalValues->Rho[xInd][yInd][zInd] = linearInterpolation(p1, p2, Rho1, Rho2, location->Z[zInd]);
    globalValues->Vs[xInd][yInd][zInd] = linearInterpolation(p1, p2, Vs1, Vs2, location->Z[zInd]);
    globalValues->Vp[xInd][yInd][zInd] = linearInterpolation(p1, p2, Vp1, Vp2, location->Z[zInd]);
    
}
Пример #15
0
qreal SprayBrush::rotationAngle()
{
    qreal rotation = 0.0;

    if (m_shapeDynamicsProperties->fixedRotation) {
        rotation = deg2rad(m_shapeDynamicsProperties->fixedAngle);
    }

    if (m_shapeDynamicsProperties->randomRotation) {

        if (m_properties->gaussian) {
            rotation = linearInterpolation(rotation , M_PI * 2.0 * qBound<qreal>(0.0, m_rand->nextGaussian(0.0, 0.50) , 1.0), m_shapeDynamicsProperties->randomRotationWeight);
        }
        else {
            rotation = linearInterpolation(rotation, M_PI * 2.0 * drand48(), m_shapeDynamicsProperties->randomRotationWeight);
        }
    }

    return rotation;
}
Пример #16
0
    // Vaporised oil-gas ratio derivative
    double MiscibilityLiveGas::dRdp(int /*region*/, double press, const surfvol_t& surfvol) const
    {
	double R = linearInterpolation(saturated_gas_table_[0],
					     saturated_gas_table_[3], press);
	double maxR = surfvol[Liquid]/surfvol[Vapour];
	if (R < maxR ) {  // Saturated case
	    return linearInterpolationDerivative(saturated_gas_table_[0],
					    saturated_gas_table_[3],
					    press);
	} else {
	    return 0.0;  // Undersaturated case
	}	
    }
Пример #17
0
    double MiscibilityLiveOil::evalR(double press, const surfvol_t& surfvol) const
    {
        if (surfvol[Vapour] == 0.0) {
            return 0.0;
        }	
	double R = linearInterpolation(saturated_oil_table_[0],
					     saturated_oil_table_[3], press);
	double maxR = surfvol[Vapour]/surfvol[Liquid];
	if (R < maxR ) {  // Saturated case
	    return R;
	} else {
	    return maxR;  // Undersaturated case
	}
    }
Пример #18
0
void Spline::smoothHandles()
{
	for (unsigned int v{ 0 }; v < m_vertices.size() - 1; ++v)
	{
		const sf::Vector2f p1{ m_vertices[v].position };
		const sf::Vector2f p2{ m_vertices[v + 1].position };
		sf::Vector2f p0{ p1 };
		sf::Vector2f p3{ p2 };
		if (v > 0)
			p0 = m_vertices[v - 1].position;
		if (v < m_vertices.size() - 2)
			p3 = m_vertices[v + 2].position;

		const sf::Vector2f m0{ linearInterpolation(p0, p1, 0.5f) };
		const sf::Vector2f m1{ linearInterpolation(p1, p2, 0.5f) };
		const sf::Vector2f m2{ linearInterpolation(p2, p3, 0.5f) };

		const float p01{ vectorLength(p1 - p0) };
		const float p12{ vectorLength(p2 - p1) };
		const float p23{ vectorLength(p3 - p2) };
		float proportion0{ 0.f };
		float proportion1{ 0.f };
		if (p01 + p12 != 0.f)
			proportion0 = p01 / (p01 + p12);
		if (p12 + p23 != 0.f)
			proportion1 = p12 / (p12 + p23);

		const sf::Vector2f q0{ linearInterpolation(m0, m1, proportion0) };
		const sf::Vector2f q1{ linearInterpolation(m1, m2, proportion1) };

		m_vertices[v].frontHandle = m1 - q0;
		m_vertices[v + 1].backHandle = m1 - q1;
	}
	m_vertices.front().backHandle = { 0.f, 0.f };
	m_vertices.back().frontHandle = { 0.f, 0.f };
}
Пример #19
0
void Spline::update()
{
	if (m_vertices.size() == 0)
	{
		m_sfmlVertices.clear();
		m_handlesVertices.clear();
		return;
	}

	const unsigned int pointsPerVertex{ m_interpolationSteps + 1u };
	m_sfmlVertices.resize(((m_vertices.size() - 1) * pointsPerVertex) + 1);

	m_handlesVertices.resize((m_vertices.size()) * 4);
	std::vector<sf::Vertex>::iterator itHandle = m_handlesVertices.begin();

	for (std::vector<Vertex>::iterator begin = m_vertices.begin(), end = m_vertices.end(), it = begin; it != end; ++it)
	{
		itHandle->color = sf::Color(255, 255, 128, 32);
		itHandle++->position = it->position;
		itHandle->color = sf::Color(0, 255, 0, 128);
		itHandle++->position = it->position + it->backHandle;
		itHandle->color = sf::Color(255, 255, 128, 32);
		itHandle++->position = it->position;
		itHandle->color = sf::Color(0, 255, 0, 128);
		itHandle++->position = it->position + it->frontHandle;

		std::vector<sf::Vertex>::iterator itSfml = m_sfmlVertices.begin() + (it - begin) * pointsPerVertex;
		if (it != end - 1)
		{
			for (unsigned int i{ 0u }; i < pointsPerVertex; ++i)
			{
				if (m_useBezier)
					itSfml->position = bezierInterpolation(it->position, (it + 1)->position, it->frontHandle, (it + 1)->backHandle, static_cast<float>(i) / pointsPerVertex);
				else
					itSfml->position = linearInterpolation(it->position, (it + 1)->position, static_cast<float>(i) / pointsPerVertex);
				itSfml->color = m_color;
				++itSfml;
			}
		}
		else
		{
			itSfml->position = it->position;
			itSfml->color = m_color;
		}
	}
}
Пример #20
0
 /**
  * Get the value of the function at x, return a quiet NAN if x is not in the definiton domain.
  **/
 virtual double _function(double x) const override
     {
     if ((_tab == nullptr) || (_len == 0)) return std::numeric_limits<double>::quiet_NaN();
     if (!((x >= _minDomain) && (x<=_maxDomain))) return std::numeric_limits<double>::quiet_NaN();
     double _e = (_maxDomain - _minDomain) / _len;
     if (!((_e >= DBL_MIN * 2) && (_e <= DBL_MAX / 2.0))) return std::numeric_limits<double>::quiet_NaN();
     int t = interpolationMethod();
     if (t == INTERPOLATION_NONE)
         {
         size_t n = (size_t)((x - _minDomain) / _e);
         if (n >= _len) return std::numeric_limits<double>::quiet_NaN();
         double y;
         try { y = (double)_tab[n]; } catch (...) { y = std::numeric_limits<double>::quiet_NaN(); }
         return y;
         }
     if (t == INTERPOLATION_LINEAR)
         {
         size_t n = (size_t)((x - _minDomain) / _e);
         if (n >= _len) std::numeric_limits<double>::quiet_NaN();
         double x1 = _minDomain + n*_e;
         double x2 = x1 + _e;
         double y1 = std::numeric_limits<double>::quiet_NaN();
         double y2 = std::numeric_limits<double>::quiet_NaN();
         try { y1 = (double)_tab[n]; } catch (...) { y1 = std::numeric_limits<double>::quiet_NaN(); }
         try { y2 = (n+1 >= _len) ? (std::numeric_limits<double>::quiet_NaN()) : ((double)_tab[n + 1]); } catch (...) { y2 = std::numeric_limits<double>::quiet_NaN(); }
         return linearInterpolation(x, fVec2(x1, y1), fVec2(x2, y2));
         }
     size_t n = (size_t)((x - _minDomain) / _e);
     if (n >= _len) std::numeric_limits<double>::quiet_NaN();
     double x1 = _minDomain + n*_e;
     double x0 = x1 - _e;
     double x2 = x1 + _e;
     double x3 = x2 + _e;
     double y0 = std::numeric_limits<double>::quiet_NaN();
     double y1 = std::numeric_limits<double>::quiet_NaN();
     double y2 = std::numeric_limits<double>::quiet_NaN();
     double y3 = std::numeric_limits<double>::quiet_NaN();
     try { y0 = (n == 0) ? (std::numeric_limits<double>::quiet_NaN()) : ((double)_tab[n - 1]); } catch (...) { y0 = std::numeric_limits<double>::quiet_NaN(); }
     try { y1 = (double)_tab[n]; } catch (...) { y1 = std::numeric_limits<double>::quiet_NaN(); }
     try { y2 = (n + 1 >= _len) ? (std::numeric_limits<double>::quiet_NaN()) : ((double)_tab[n + 1]); } catch (...) { y2 = std::numeric_limits<double>::quiet_NaN(); }
     try { y3 = (n + 2 >= _len) ? (std::numeric_limits<double>::quiet_NaN()) : ((double)_tab[n + 2]); } catch (...) { y3 = std::numeric_limits<double>::quiet_NaN(); }
     if (t == INTERPOLATION_CUBIC) return cubicInterpolation(x, fVec2(x0, y0), fVec2(x1, y1), fVec2(x2, y2), fVec2(x3, y3));
     return monotoneCubicInterpolation(x, fVec2(x0, y0), fVec2(x1, y1), fVec2(x2, y2), fVec2(x3, y3));
     }
Пример #21
0
    void MiscibilityLiveOil::evalRDeriv(const double press, const surfvol_t& surfvol,
                                        double& R, double& dRdp) const
    {
        if (surfvol[Vapour] == 0.0) {
            R = 0.0;
            dRdp = 0.0;
            return;
        }
	R = linearInterpolation(saturated_oil_table_[0],
                                      saturated_oil_table_[3], press);
	double maxR = surfvol[Vapour]/surfvol[Liquid];
	if (R < maxR ) {
            // Saturated case
	    dRdp = linearInterpolationDerivative(saturated_oil_table_[0],
					    saturated_oil_table_[3],
					    press);
	} else {
            // Undersaturated case
            R = maxR;
	    dRdp = 0.0;
	}
    }
float SimpleJetCorrectionUncertainty::uncertaintyBin(unsigned fBin, float fY, bool fDirection) const 
{
  if (fBin >= mParameters->size()) 
    //throw cms::Exception("SimpleJetCorrectionUncertainty")<<" wrong bin: "<<fBin<<": only "<<mParameters->size()<<" are available";
    handleError("SimpleJetCorrectionUncertainty"," wrong bin"); 
  const std::vector<float>& p = mParameters->record(fBin).parameters();
  if ((p.size() % 3) != 0)
    //throw cms::Exception ("SimpleJetCorrectionUncertainty")<<"wrong # of parameters: multiple of 3 expected, "<<p.size()<< " got";    
    handleError("SimpleJetCorrectionUncertainty"," wrong # of parameters: multiple of 3 expected"); 
  std::vector<float> yGrid,value;
  unsigned int N = p.size()/3;
  float result = -1.0;
  for(unsigned i=0;i<N;i++)
    {
      unsigned ind = 3*i;
      yGrid.push_back(p[ind]);
      if (fDirection)// true = UP
        value.push_back(p[ind+1]);
      else // false = DOWN
        value.push_back(p[ind+2]); 
    }
  if (fY <= yGrid[0])
    result = value[0];  
  else if (fY >= yGrid[N-1])
    result = value[N-1]; 
  else
    {
      int bin = findBin(yGrid,fY); 
      float vx[2],vy[2];
      for(int i=0;i<2;i++)
        {
          vx[i] = yGrid[bin+i]; 
          vy[i] = value[bin+i];
        } 
      result = linearInterpolation(fY,vx,vy);
    }
  return result;
}
Пример #23
0
std::vector<float> PdfTransfer::SinglePdfTransfer(Histogram *input, Histogram *palette) {
	/*float *original = new float[ bin_count + 3];
	float *target = new float[ bin_count + 3];*/
	std::vector<float> original(bin_count + 1);
	std::vector<float> target(bin_count + 1);
	unsigned int globalIC = input->getGlobalCounter();
	unsigned int globalTC = palette->getGlobalCounter();
	std::vector<float> finalO(bin_count + 3);
	std::vector<float> finalT(bin_count + 3);
	std::vector<float> values(bin_count + 3);
	//to help maintain the interpolation correct
	finalO[0] = 0;
	original[0] = (float) input[0].getCounter();
	finalO[1] = original[0] / globalIC;
	finalO[bin_count + 2] = (float) bin_count + 1;

	finalT[0] = 0;
	target[0] = (float) palette[0].getCounter();
	finalT[1] = target[0] / globalTC;
	finalT[bin_count + 2] = (float) bin_count + 1;

	for (unsigned int i = 1; i <= bin_count; ++i) {
		original[i] = original[i - 1] + input[i].getCounter();
		finalO[i + 1] = original[i] / globalIC;

		target[i] = target[i - 1] + palette[i].getCounter();
		finalT[i + 1] = target[i] / globalTC;
	}

	//populate values
	values[0] = 0.0;
	for (unsigned int i = 1; i < bin_count + 3; ++i) {
		values[i] = (float) i - 1;
	}
	return linearInterpolation(finalT, values, finalO);
}
Пример #24
0
void SprayBrush::paint(KisPaintDeviceSP dab, KisPaintDeviceSP source,
                       const KisPaintInformation& info, qreal rotation, qreal scale,
                       const KoColor &color, const KoColor &bgColor)
{
    // initializing painter
    if (!m_painter) {
        m_painter = new KisPainter(dab);
        m_painter->setFillStyle(KisPainter::FillStyleForegroundColor);
        m_painter->setMaskImageSize(m_shapeProperties->width, m_shapeProperties->height);
        m_dabPixelSize = dab->colorSpace()->pixelSize();
        if (m_colorProperties->useRandomHSV) {
            m_transfo = dab->colorSpace()->createColorTransformation("hsv_adjustment", QHash<QString, QVariant>());
        }

        m_brushQImage = m_shapeProperties->image;
        if (!m_brushQImage.isNull()) {
            m_brushQImage = m_brushQImage.scaled(m_shapeProperties->width, m_shapeProperties->height);
        }
        m_imageDevice = new KisPaintDevice(dab->colorSpace());
    }


    qreal x = info.pos().x();
    qreal y = info.pos().y();
    KisRandomAccessorSP accessor = dab->createRandomAccessorNG(qRound(x), qRound(y));

    Q_ASSERT(color.colorSpace()->pixelSize() == dab->pixelSize());
    m_inkColor = color;
    KisCrossDeviceColorPicker colorPicker(source, m_inkColor);

    // apply size sensor
    m_radius = m_properties->radius * scale;

    // jitter movement
    if (m_properties->jitterMovement) {
        x = x + ((2 * m_radius * drand48()) - m_radius) * m_properties->amount;
        y = y + ((2 * m_radius * drand48()) - m_radius) * m_properties->amount;
    }

    // this is wrong for every shape except pixel and anti-aliased pixel


    if (m_properties->useDensity) {
        m_particlesCount = (m_properties->coverage * (M_PI * m_radius * m_radius));
    }
    else {
        m_particlesCount = m_properties->particleCount;
    }

    QHash<QString, QVariant> params;
    qreal nx, ny;
    int ix, iy;

    qreal angle;
    qreal length;
    qreal rotationZ = 0.0;
    qreal particleScale = 1.0;

    bool shouldColor = true;
    if (m_colorProperties->fillBackground) {
        m_painter->setPaintColor(bgColor);
        paintCircle(m_painter, x, y, m_radius);
    }

    QTransform m;
    m.reset();
    m.rotateRadians(-rotation + deg2rad(m_properties->brushRotation));
    m.scale(m_properties->scale, m_properties->scale);

    for (quint32 i = 0; i < m_particlesCount; i++) {
        // generate random angle
        angle = drand48() * M_PI * 2;

        // generate random length
        if (m_properties->gaussian) {
            length = qBound<qreal>(0.0, m_rand->nextGaussian(0.0, 0.50) , 1.0);
        }
        else {
            length = drand48();
        }

        if (m_shapeDynamicsProperties->enabled) {
            // rotation
            rotationZ = rotationAngle();

            if (m_shapeDynamicsProperties->followCursor) {

                rotationZ = linearInterpolation(rotationZ, angle, m_shapeDynamicsProperties->followCursorWeigth);
            }


            if (m_shapeDynamicsProperties->followDrawingAngle) {

                rotationZ = linearInterpolation(rotationZ, info.drawingAngle(), m_shapeDynamicsProperties->followDrawingAngleWeight);
            }

            // random size - scale
            if (m_shapeDynamicsProperties->randomSize) {
                particleScale = drand48();
            }
        }
        // generate polar coordinate
        nx = (m_radius * cos(angle)  * length);
        ny = (m_radius * sin(angle)  * length);

        // compute the height of the ellipse
        ny *= m_properties->aspect;

        // transform
        m.map(nx, ny, &nx, &ny);

        // color transformation

        if (shouldColor) {
            if (m_colorProperties->sampleInputColor) {
                colorPicker.pickOldColor(nx + x, ny + y, m_inkColor.data());
            }

            // mix the color with background color
            if (m_colorProperties->mixBgColor) {
                KoMixColorsOp * mixOp = dab->colorSpace()->mixColorsOp();

                const quint8 *colors[2];
                colors[0] = m_inkColor.data();
                colors[1] = bgColor.data();

                qint16 colorWeights[2];
                int MAX_16BIT = 255;
                qreal blend = info.pressure();

                colorWeights[0] = static_cast<quint16>(blend * MAX_16BIT);
                colorWeights[1] = static_cast<quint16>((1.0 - blend) * MAX_16BIT);
                mixOp->mixColors(colors, colorWeights, 2, m_inkColor.data());
            }

            if (m_colorProperties->useRandomHSV && m_transfo) {
                params["h"] = (m_colorProperties->hue / 180.0) * drand48();
                params["s"] = (m_colorProperties->saturation / 100.0) * drand48();
                params["v"] = (m_colorProperties->value / 100.0) * drand48();
                m_transfo->setParameters(params);
                m_transfo->transform(m_inkColor.data(), m_inkColor.data() , 1);
            }

            if (m_colorProperties->useRandomOpacity) {
                quint8 alpha = qRound(drand48() * OPACITY_OPAQUE_U8);
                m_inkColor.setOpacity(alpha);
                m_painter->setOpacity(alpha);
            }

            if (!m_colorProperties->colorPerParticle) {
                shouldColor = false;
            }
            m_painter->setPaintColor(m_inkColor);
        }

        qreal jitteredWidth = qMax(qreal(1.0), m_shapeProperties->width * particleScale);
        qreal jitteredHeight = qMax(qreal(1.0), m_shapeProperties->height * particleScale);

        if (m_shapeProperties->enabled){
        switch (m_shapeProperties->shape){
            // ellipse
            case 0:
            {
                if (m_shapeProperties->width == m_shapeProperties->height){
                    paintCircle(m_painter, nx + x, ny + y, qRound(jitteredWidth * 0.5));
                }
                else {
                    paintEllipse(m_painter, nx + x, ny + y, qRound(jitteredWidth * 0.5) , qRound(jitteredHeight * 0.5), rotationZ);
                }
                break;
            }
            // rectangle
            case 1:
            {
                paintRectangle(m_painter, nx + x, ny + y, qRound(jitteredWidth) , qRound(jitteredHeight), rotationZ);
                break;
            }
            // wu-particle
            case 2: {
                paintParticle(accessor, m_inkColor, nx + x, ny + y);
                break;
            }
            // pixel
            case 3: {
                ix = qRound(nx + x);
                iy = qRound(ny + y);
                accessor->moveTo(ix, iy);
                memcpy(accessor->rawData(), m_inkColor.data(), m_dabPixelSize);
                break;
            }
            case 4: {
                if (!m_brushQImage.isNull()) {

                    QTransform m;
                    m.rotate(rad2deg(rotationZ));

                    if (m_shapeDynamicsProperties->randomSize) {
                        m.scale(particleScale, particleScale);
                    }
                    m_transformed = m_brushQImage.transformed(m, Qt::SmoothTransformation);
                    m_imageDevice->convertFromQImage(m_transformed, 0);
                    KisRandomAccessorSP ac = m_imageDevice->createRandomAccessorNG(0, 0);
                    QRect rc = m_transformed.rect();

                    if (m_colorProperties->useRandomHSV && m_transfo) {

                        for (int y = rc.y(); y < rc.y() + rc.height(); y++) {
                            for (int x = rc.x(); x < rc.x() + rc.width(); x++) {
                                ac->moveTo(x, y);
                                m_transfo->transform(ac->rawData(), ac->rawData() , 1);
                            }
                        }
                    }

                    ix = qRound(nx + x - rc.width() * 0.5);
                    iy = qRound(ny + y - rc.height() * 0.5);
                    m_painter->bitBlt(QPoint(ix, iy), m_imageDevice, rc);
                    m_imageDevice->clear();
                    break;
                }
            }
            }
            // Auto-brush
        }
        else {
            QPointF hotSpot = m_brush->hotSpot(particleScale, particleScale, -rotationZ, info);
            QPointF pos(nx + x, ny + y);
            QPointF pt = pos - hotSpot;

            qint32 ix;
            qreal xFraction;
            qint32 iy;
            qreal yFraction;

            KisPaintOp::splitCoordinate(pt.x(), &ix, &xFraction);
            KisPaintOp::splitCoordinate(pt.y(), &iy, &yFraction);

            //KisFixedPaintDeviceSP dab;
            if (m_brush->brushType() == IMAGE ||
                    m_brush->brushType() == PIPE_IMAGE) {
                m_fixedDab = m_brush->paintDevice(m_fixedDab->colorSpace(), particleScale, -rotationZ, info, xFraction, yFraction);

                if (m_colorProperties->useRandomHSV && m_transfo) {
                    quint8 * dabPointer = m_fixedDab->data();
                    int pixelCount = m_fixedDab->bounds().width() * m_fixedDab->bounds().height();
                    m_transfo->transform(dabPointer, dabPointer, pixelCount);
                }

            }
            else {
                m_brush->mask(m_fixedDab, m_inkColor, particleScale, particleScale, -rotationZ, info, xFraction, yFraction);
            }
            m_painter->bltFixed(QPoint(ix, iy), m_fixedDab, m_fixedDab->bounds());
        }
    }
    // recover from jittering of color,
    // m_inkColor.opacity is recovered with every paint
}
double NonlinearTransmission::lookupActuatorPosition(double joint_position){
  return linearInterpolation(joint_position_samples_, actuator_position_samples_, joint_position);
}
Пример #26
0
bool PdfTransfer::NDPdfTransfer(float *input, float *palette, float **rotations) {
	clock_t start, end;
	FILE *fp = fopen("time.txt", "w");
	unsigned long int var_time = 0;

	float *finalPic = new float[_projections * _inputSize];

	for (unsigned int i = 0; i < _iterations; ++i) {
		start = clock();
		float * ptrRotation = rotations[i];
		assert(ptrRotation);

		float *inputRotation = new float[_projections * _inputSize];
		float *paletteRotation = new float[_projections * _paletteSize];

		_matrixModule->matrix_multiply(ptrRotation, _projections, NUM_CHANNELS,
			input, NUM_CHANNELS, _inputSize, inputRotation, _projections, _inputSize);
#ifdef DEBUG
		if (!i) {
			printMatrix(ptrRotation, _projections, NUM_CHANNELS, "ptrRotation", _height, _width);
			printMatrix(input, NUM_CHANNELS, _inputSize, "input", _height, _width);
			printMatrix(inputRotation, _projections, _inputSize, "inputRotation", _height, _width);
		}
#endif
		_matrixModule->matrix_multiply(ptrRotation, _projections, NUM_CHANNELS,
			palette, NUM_CHANNELS, _paletteSize, paletteRotation, _projections, _paletteSize);

#ifdef DEBUG
		if (!i) {
			printMatrix(palette, NUM_CHANNELS, _paletteSize, "palette", _height, _width);
			printMatrix(paletteRotation, _projections, _paletteSize, "paletteRotation", _height, _width);
		}
#endif

		Histogram ** histogramsInput = new Histogram*[_projections];
		Histogram ** histogramsPalette = new Histogram*[_projections];

		//Step1: Creation of Histograms
		CreateHistograms(inputRotation, _inputSize,
			paletteRotation, _paletteSize, _projections, histogramsInput, histogramsPalette);


#ifdef DEBUG
		printHistogr(histogramsInput, i);
#endif

		std::vector<float> *inter = new std::vector<float>[_projections];
		for (unsigned int j = 0; j < _projections; ++j) {
			std::vector<float> ptr = SinglePdfTransfer(histogramsInput[j], histogramsPalette[j]);

			std::vector<float> newPtr(ptr.begin() + 1, ptr.end() - 1);
			float scale = bin_count / (histogramsInput[j]->GetOverallMax() -
				histogramsInput[j]->GetOverallMin());

			//populate X points before interpolation
			std::vector<float> X(newPtr.size());
			for (unsigned int k = 0; k < X.size(); ++k) {
				X[k] = (float) k;
			}
			std::vector<float> Xq(_inputSize);
			unsigned int itr = 0;
			for (unsigned k = j * _inputSize; k < (j + 1) * _inputSize; ++k, ++itr) {
				Xq[itr] = inputRotation[k];
				Xq[itr] = (Xq[itr] - histogramsInput[j]->GetOverallMin()) * scale;
			}


			inter[j] = linearInterpolation(X, newPtr, Xq);

			for (unsigned int k = 0; k < inter[j].size(); ++k) {
				inter[j][k] = inter[j][k] / scale + histogramsInput[j]->GetOverallMin();
				inter[j][k] -= matrix_access(inputRotation, _projections, _inputSize, j, k);
				matrix_access(finalPic, _projections, _inputSize, j, k) = inter[j][k];

			}
		}

#ifdef DEBUG
		char filename2[10];
		sprintf(filename2, "finalPic%d", i);
		printMatrix(finalPic, _projections, _inputSize, filename2, _height, _width);

#endif
		//resolve linear system of ptrRotation*x = inter
		_matrixModule->matrix_inverse(ptrRotation, _projections, NUM_CHANNELS);
		float *aux = new float[ _projections * _inputSize ];
		_matrixModule->matrix_multiply(ptrRotation, _projections, NUM_CHANNELS,
			finalPic, _projections, _inputSize,
			aux, _projections, _inputSize);
		_matrixModule->matrix_add(input, aux, input, _projections, _inputSize);


#ifdef DEBUG
		//if(!i)
		//{
		char filename[10];
		sprintf(filename, "iter%d", i);
		printMatrix(input, _projections, _inputSize, filename, _height, _width);
		//}
#endif

		end = clock();
		var_time = (end - start) / (CLOCKS_PER_SEC);
		fprintf(fp, "It took %lu seconds to complete %d iteration\n", var_time, i);

		//freeing memory
		delete [] inputRotation;
		delete [] paletteRotation;

	}

	//freeing heap
	delete [] finalPic;

	//used for logging time
	fclose(fp);
	return true;
}
double NonlinearTransmission::lookupReductionByInput(double actuator_position){
  return linearInterpolation(actuator_position_samples_, mechanical_reduction_samples_, actuator_position);
}
double NonlinearTransmission::lookupReductionByOutput(double joint_position){
  return linearInterpolation(joint_position_samples_, mechanical_reduction_samples_, joint_position);
}
Пример #29
0
    double MiscibilityLiveGas::miscible_gas(double press, const surfvol_t& surfvol, int item,
					    bool deriv) const
    {
	int section;
	double R = linearInterpolation(saturated_gas_table_[0],
					     saturated_gas_table_[3], press,
					     section);
	double maxR = surfvol[Liquid]/surfvol[Vapour];
	if (deriv) {
	    if (R < maxR ) {  // Saturated case
		return linearInterpolationDerivative(saturated_gas_table_[0],
						saturated_gas_table_[item],
						press);
	    } else {  // Undersaturated case
		int is = section;
		if (undersat_gas_tables_[is][0].size() < 2) {
		    double val = (saturated_gas_table_[item][is+1]
				  - saturated_gas_table_[item][is]) /
			(saturated_gas_table_[0][is+1] -
			 saturated_gas_table_[0][is]);
		    return val;
		}
		double val1 =
		    linearInterpolation(undersat_gas_tables_[is][0],
					      undersat_gas_tables_[is][item],
					      maxR);
		double val2 = 
		    linearInterpolation(undersat_gas_tables_[is+1][0],
					      undersat_gas_tables_[is+1][item],
					      maxR);
		double val = (val2 - val1)/
		    (saturated_gas_table_[0][is+1] - saturated_gas_table_[0][is]);
		return val;
	    }
	} else {
	    if (R < maxR ) {  // Saturated case
		return linearInterpolation(saturated_gas_table_[0],
						 saturated_gas_table_[item],
						 press);
	    } else {  // Undersaturated case
		int is = section;
		// Extrapolate from first table section
		if (is == 0 && press < saturated_gas_table_[0][0]) {
		    return linearInterpolation(undersat_gas_tables_[0][0],
						     undersat_gas_tables_[0][item],
						     maxR);
		}

		// Extrapolate from last table section
		int ltp = saturated_gas_table_[0].size() - 1;
		if (is+1 == ltp && press > saturated_gas_table_[0][ltp]) {
		    return linearInterpolation(undersat_gas_tables_[ltp][0],
						     undersat_gas_tables_[ltp][item],
						     maxR);
		}

		// Interpolate between table sections
		double w = (press - saturated_gas_table_[0][is]) /
		    (saturated_gas_table_[0][is+1] - 
		     saturated_gas_table_[0][is]);
		if (undersat_gas_tables_[is][0].size() < 2) {
		    double val = saturated_gas_table_[item][is] +
			w*(saturated_gas_table_[item][is+1] -
			   saturated_gas_table_[item][is]);
		    return val;
		}
		double val1 =
		    linearInterpolation(undersat_gas_tables_[is][0],
					      undersat_gas_tables_[is][item],
					      maxR);
		double val2 = 
		    linearInterpolation(undersat_gas_tables_[is+1][0],
					      undersat_gas_tables_[is+1][item],
					      maxR);
		double val = val1 + w*(val2 - val1);
		return val;
	    }
	}
    }
Пример #30
0
			/**
			* Get the value of the function at x, return a quiet NAN if x is not in the definiton domain.
			**/
			virtual double _function(double x) const override
				{
				if (_pmap->size() == 0)	{ return  std::numeric_limits<double>::quiet_NaN(); }
				_minDomain = (_pmap->begin())->first;
				_maxDomain = (_pmap->rbegin())->first;
				if ((x < _minDomain)||(x > _maxDomain)) { return  std::numeric_limits<double>::quiet_NaN(); }
				
				auto it2 = _pmap->lower_bound(x);
				if (it2 == _pmap->end()) { return  std::numeric_limits<double>::quiet_NaN(); }
				if (it2 == _pmap->begin()) { if (x < (double)(it2->first)) { return  std::numeric_limits<double>::quiet_NaN(); } else { return it2->second; } }
				
				double x2 = (double)it2->first;
				double y2 = (double)it2->second;
				auto it1 = it2; it1--;
				double x1 = (double)it1->first;
				double y1 = (double)it1->second;

				int t = interpolationMethod();
				if (t == INTERPOLATION_NONE) { return y1; }
				if (t == INTERPOLATION_LINEAR) { return linearInterpolation(x, fVec2(x1, y1), fVec2(x2, y2)); }

				double x0 = x1 - 1.0;
				double x3 = x2 + 1.0;
				double y0 = std::numeric_limits<double>::quiet_NaN();
				double y3 = std::numeric_limits<double>::quiet_NaN();
				if (it1 != _pmap->begin())
					{
					it1--;
				    x0 = (double)it1->first;
					y0 = (double)it1->second;
					}
				it2++;
				if (it2 != _pmap->end())
					{
					x3 = (double)it2->first;
					y3 = (double)it2->second;
					}
				if (t == INTERPOLATION_CUBIC) return cubicInterpolation(x, fVec2(x0, y0), fVec2(x1, y1), fVec2(x2, y2), fVec2(x3, y3));
				return monotoneCubicInterpolation(x, fVec2(x0, y0), fVec2(x1, y1), fVec2(x2, y2), fVec2(x3, y3));

				/*
				if ((_tab == nullptr) || (_len == 0)) return std::numeric_limits<double>::quiet_NaN();
				if (!((x >= _minDomain) && (x <= _maxDomain))) return std::numeric_limits<double>::quiet_NaN();
				double _e = (_maxDomain - _minDomain) / _len;
				if (!((_e >= DBL_MIN * 2) && (_e <= DBL_MAX / 2.0))) return std::numeric_limits<double>::quiet_NaN();
				int t = interpolationMethod();
				if (t == INTERPOLATION_NONE)
					{
					size_t n = (size_t)((x - _minDomain) / _e);
					if (n >= _len) return std::numeric_limits<double>::quiet_NaN();
					double y;
					try { y = (double)_tab[n]; }
					catch (...) { y = std::numeric_limits<double>::quiet_NaN(); }
					return y;
					}
				if (t == INTERPOLATION_LINEAR)
					{
					size_t n = (size_t)((x - _minDomain) / _e);
					if (n >= _len) std::numeric_limits<double>::quiet_NaN();
					double x1 = _minDomain + n*_e;
					double x2 = x1 + _e;
					double y1 = std::numeric_limits<double>::quiet_NaN();
					double y2 = std::numeric_limits<double>::quiet_NaN();
					try { y1 = (double)_tab[n]; }
					catch (...) { y1 = std::numeric_limits<double>::quiet_NaN(); }
					try { y2 = (n + 1 >= _len) ? (std::numeric_limits<double>::quiet_NaN()) : ((double)_tab[n + 1]); }
					catch (...) { y2 = std::numeric_limits<double>::quiet_NaN(); }
					return linearInterpolation(x, fVec2(x1, y1), fVec2(x2, y2));
					}
				size_t n = (size_t)((x - _minDomain) / _e);
				if (n >= _len) std::numeric_limits<double>::quiet_NaN();
				double x1 = _minDomain + n*_e;
				double x0 = x1 - _e;
				double x2 = x1 + _e;
				double x3 = x2 + _e;
				double y0 = std::numeric_limits<double>::quiet_NaN();
				double y1 = std::numeric_limits<double>::quiet_NaN();
				double y2 = std::numeric_limits<double>::quiet_NaN();
				double y3 = std::numeric_limits<double>::quiet_NaN();
				try { y0 = (n == 0) ? (std::numeric_limits<double>::quiet_NaN()) : ((double)_tab[n - 1]); }
				catch (...) { y0 = std::numeric_limits<double>::quiet_NaN(); }
				try { y1 = (double)_tab[n]; }
				catch (...) { y1 = std::numeric_limits<double>::quiet_NaN(); }
				try { y2 = (n + 1 >= _len) ? (std::numeric_limits<double>::quiet_NaN()) : ((double)_tab[n + 1]); }
				catch (...) { y2 = std::numeric_limits<double>::quiet_NaN(); }
				try { y3 = (n + 2 >= _len) ? (std::numeric_limits<double>::quiet_NaN()) : ((double)_tab[n + 2]); }
				catch (...) { y3 = std::numeric_limits<double>::quiet_NaN(); }
				if (t == INTERPOLATION_CUBIC) return cubicInterpolation(x, fVec2(x0, y0), fVec2(x1, y1), fVec2(x2, y2), fVec2(x3, y3));
				return monotoneCubicInterpolation(x, fVec2(x0, y0), fVec2(x1, y1), fVec2(x2, y2), fVec2(x3, y3));
				*/
				}