/// <summary> /// See the documentation on the base class. /// <seealso cref="Module"/> /// </summary> /// <param name="x">X coordinate</param> /// <param name="y">Y coordinate</param> /// <param name="z">Z coordinate</param> /// <returns>Returns the computed value</returns> public override double GetValue(double x, double y, double z) { // Get the output value from the source module. double sourceValue = this.SourceModules[0].GetValue(x, y, z); // Find the first element in the control point array that has an input value // larger than the output value from the source module. int indexPos; for (indexPos = 0; indexPos < this.controlPoints.Count; indexPos++) { if (sourceValue < this.controlPoints[indexPos].InputValue) { break; } } // Find the four nearest control points so that we can perform cubic // interpolation. int index0 = NoiseMath.Clamp(indexPos - 2, 0, this.controlPoints.Count - 1); int index1 = NoiseMath.Clamp(indexPos - 1, 0, this.controlPoints.Count - 1); int index2 = NoiseMath.Clamp(indexPos, 0, this.controlPoints.Count - 1); int index3 = NoiseMath.Clamp(indexPos + 1, 0, this.controlPoints.Count - 1); // If some control points are missing (which occurs if the value from the // source module is greater than the largest input value or less than the // smallest input value of the control point array), get the corresponding // output value of the nearest control point and exit now. if (index1 == index2) { return(this.controlPoints[index1].OutputValue); } // Compute the alpha value used for cubic interpolation. double input0 = this.controlPoints[index1].InputValue; double input1 = this.controlPoints[index2].InputValue; double alpha = (sourceValue - input0) / (input1 - input0); // Now perform the cubic interpolation given the alpha value. return(NoiseMath.Cubic( this.controlPoints[index0].OutputValue, this.controlPoints[index1].OutputValue, this.controlPoints[index2].OutputValue, this.controlPoints[index3].OutputValue, alpha)); }