The gColor
Colour Spline
Site Map Feedback

Download:

Up Colour Spline HSL HSV Mixers Shaders

One gColor method provides a powerful means of automating color selection; it interpolates an array of colors which a user would normally set using a Color Bar. This version uses doubles throughout making it particularly suitable for generating complex procedural textures where the colors are being processed many times before rendering. If the array is simply black followed by white, t=0 will return black, t=0.3 will return dark grey, t=0.5 is mid grey, t=0.8 is light grey and t=1 will be white. The Alpha Channel is included in the Interpolation. There is a choice of interpolation method, the differences are discussed below.

  enum ColorSplineInterpolationType {LinearCSI,HermiteCSI,bSplineCSI,CatmullRomCSI};
  gColor SetFromSpline(double t, int Count, gColor* Colors, double* Positions=0, ColorSplineInterpolationType Interpolation=CatmullRomCSI);
The method takes the parameter, t (which should be in the interval [0,1]); Count is the number of entries in the Colors array. If Positions is zero, the colors are equally spaced; otherwise Positions should point to an array of Count doubles which vary from zero to one. The entries do need to be in order, but do not need to include a value for the end positions (0 or 1).

In the following images I have used this array of colors: Black,Red,Yellow,White,Blue. The first set of images use all five colors with Positions=0, so they are equally spaced:
Equally Spaced Color Splines
Linear is obviously a straight-line interpolation and results in a banded appearance. Hermite 'eases' the linear interpolation with a Hermite Step to the specified color at the specified Position. CatmullRom still hits each color at the correct position and smooths the rate of color-change well by over-shooting, though this will be clipped for full brightness. The vertical lines on the bSpline method are the true colors at their Position, illustrating that although bSpline does a good job of blending the colors, it never reaches the defined colors: the whole image is darker than the others. In short, bSpine is smooth but not accurate and cannot reach the correct brightness; CatmullRom is accurate and smooth until it gets clipped; Hermite is accurate and fairly smooth; and linear is accurate but will have sharp changes in color at each Color Position.

In this image, the positions have been set for each color set as follows: Black=0; Red=0.2; Yellow=0.7; White=0.9; Blue=1;
Color Spline with Positioned Colors
The last image shows what happens if the first and last colors are not at positions 0 and 1. The colors were set as follows: Black=0.1; Red=0.2; Yellow=0.7; White=0.9;
Color Spline with Positioned Colors but no color at position zero or one
Here's the code used to draw these images:

  gColor Colors[5];
  double Positions[]={0, 0.2, 0.7, 0.9, 1};
  Colors[0].Set(0x000000);  // Black
  Colors[1].Set(0xC00000);  // Dull Red
  Colors[2].Set(0xC0C000);  // Dull Yellow
  Colors[3].Set(0xC0C0C0);  // Dull White
  Colors[4].Set(0x0000C0);  // Dull Blue
  for(WORD x=GetWidth(); x--;) {
    double t=double(x)/GetWidth();  // t is how far along: range [0,1]
    DWORD dw=Color1.SetFromSpline(t, 5, Colors,Positions, gColor::bSplineCSI).GetRGB();
    for(WORD y=GetHeight(); y--;)  SetPixel(x,y, dw);  // Vertical colored line
    SetPixel(x, WORD(Round(gFilters::InterpolateLinear((         0xC0)/255.0, GetHeight(),0))), 0xC0C0C0);  // Horizontal grey line showing maximum level
    SetPixel(x, WORD(Round(gFilters::InterpolateLinear(( dw     &0xFF)/255.0, GetHeight(),0))), 0x0000FF);  // Red graph line
    SetPixel(x, WORD(Round(gFilters::InterpolateLinear(((dw>> 8)&0xFF)/255.0, GetHeight(),0))), 0x00FF00);  // Green graph line
    SetPixel(x, WORD(Round(gFilters::InterpolateLinear(((dw>>16)&0xFF)/255.0, GetHeight(),0))), 0xFF0000);  // Blue graph line
  }


THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.