/// <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 sourceModuleValue = SourceModules[0].GetValue(x, y, z); // Find the first element in the control point array that has a value // larger than the output value from the source module. int indexPos; for (indexPos = 0; indexPos < ControlPoints.Count; indexPos++) { if (sourceModuleValue < ControlPoints[indexPos].x) { break; } } // Find the two nearest control points so that we can map their values // onto a quadratic curve. var index0 = NoiseMath.Clamp(indexPos - 1, 0, ControlPoints.Count - 1); var index1 = NoiseMath.Clamp(indexPos, 0, ControlPoints.Count - 1); // If some control points are missing (which occurs if the output value from // the source module is greater than the largest value or less than the // smallest value of the control point array), get the value of the nearest // control point and exit now. if (index0 == index1) { return(ControlPoints[index1].x); } // Compute the alpha value used for linear interpolation. var value0 = ControlPoints[index0].x; var value1 = ControlPoints[index1].x; var alpha = (sourceModuleValue - value0) / (value1 - value0); if (InvertTerraces) { alpha = 1.0 - alpha; NoiseMath.Swap(ref value0, ref value1); } // Squaring the alpha produces the terrace effect. alpha *= alpha; // Now perform the linear interpolation given the alpha value. return(NoiseMath.Linear(value0, value1, alpha)); }
/// <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)); }
/// <summary> /// Calculates the destination color. /// </summary> /// <param name="sourceColor">The source color generated from the color /// gradient.</param> /// <param name="backgroundColor">The color from the background image at the /// corresponding position.</param> /// <param name="lightValue">The intensity of the light at that position.</param> /// <returns>The destination color.</returns> Color CalcDestinationColor(Color sourceColor, Color backgroundColor, double lightValue) { var sourceRed = (double)sourceColor.Red / 255.0; var sourceGreen = (double)sourceColor.Green / 255.0; var sourceBlue = (double)sourceColor.Blue / 255.0; var sourceAlpha = (double)sourceColor.Alpha / 255.0; var backgroundRed = (double)backgroundColor.Red / 255.0; var backgroundGreen = (double)backgroundColor.Green / 255.0; var backgroundBlue = (double)backgroundColor.Blue / 255.0; // First, blend the source color to the background color using the alpha // of the source color. var red = NoiseMath.Linear(backgroundRed, sourceRed, sourceAlpha); var green = NoiseMath.Linear(backgroundGreen, sourceGreen, sourceAlpha); var blue = NoiseMath.Linear(backgroundBlue, sourceBlue, sourceAlpha); if (EnableLight) { // Now calculate the light color. var lightRed = lightValue * (double)LightColor.Red / 255.0; var lightGreen = lightValue * (double)LightColor.Green / 255.0; var lightBlue = lightValue * (double)LightColor.Blue / 255.0; // Apply the light color to the new color. red *= lightRed; green *= lightGreen; blue *= lightBlue; } // Clamp the color channels to the (0..1) range. red = NoiseMath.Clamp(red, 0, 1); green = NoiseMath.Clamp(green, 0, 1); blue = NoiseMath.Clamp(blue, 0, 1); // Rescale the color channels to the (0..255) range and return // the new color. Color newColor = new Color( (byte)((int)(red * 255) & 0xff), (byte)((int)(green * 255) & 0xff), (byte)((int)(blue * 255) & 0xff), Math.Max(sourceColor.Alpha, backgroundColor.Alpha)); return(newColor); }
/// <summary> /// Returns the color at the specified position in the color gradient. /// </summary> /// <param name="gradientPosition">The specified position.</param> /// <returns>The color at that position.</returns> public Color GetColor(double gradientPosition) { // Find the first element in the gradient point array that has a gradient // position larger than the gradient position passed to this method. int indexPos; for (indexPos = 0; indexPos < gradientPoints.Count; indexPos++) { if (gradientPosition < gradientPoints[indexPos].Position) { break; } } // Find the two nearest gradient points so that we can perform linear // interpolation on the color. var index0 = NoiseMath.Clamp(indexPos - 1, 0, gradientPoints.Count - 1); var index1 = NoiseMath.Clamp(indexPos, 0, gradientPoints.Count - 1); // If some gradient points are missing (which occurs if the gradient // position passed to this method is greater than the largest gradient // position or less than the smallest gradient position in the array), get // the corresponding gradient color of the nearest gradient point and exit // now. if (index0 == index1) { return(gradientPoints[index1].Color); } // Compute the alpha value used for linear interpolation. var input0 = gradientPoints[index0].Position; var input1 = gradientPoints[index1].Position; var alpha = (gradientPosition - input0) / (input1 - input0); // Now perform the linear interpolation given the alpha value. var color0 = gradientPoints[index0].Color; var color1 = gradientPoints[index1].Color; return(Color.LinearInterpColor(color0, color1, (float)alpha)); }
/// <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) { return(NoiseMath.Clamp(SourceModules[0].GetValue(x, y, z), LowerBound, UpperBound)); }
public void Math_Clamp_OutOfRange_Upper_Test() { var expected = 10; Assert.AreEqual(expected, NoiseMath.Clamp(15, 0, expected)); }
public void Math_Clamp_OutOfRange_Lower_Test() { var expected = 10; Assert.AreEqual(expected, NoiseMath.Clamp(5, expected, 20)); }
public void Math_Clamp_InRange_Test() { var expected = 5; Assert.AreEqual(expected, NoiseMath.Clamp(expected, 0, 10)); }
public void ClampInRangeTest(double data) { Assert.InRange(data, -1.0, 1.0); Assert.Equal(data, NoiseMath.Clamp(data, -1.0, 1.0)); }
public void ClampOutOfRangeTest(double data) { Assert.NotInRange(data, -1.0, 1.0); Assert.InRange(NoiseMath.Clamp(data, -1.0, 1.0), -1.0, 1.0); }