Juce::ColourGradient Suggestions


#1

Hi Jules,

Instead of having free-standing functions floating around in my code, I would like to suggest adding methods to flip a gradient’s points, as well as reversing its colours without modifying the ColourPoint positions:

void flip() //Cleaner than calling std::swap spuriously in my code, I find...
{
    std::swap (point1, point2);
}
void reverse()
{
    Array <ColourPoint> reversed;

    for (int i = 0; i < colours.size(); ++i)
    {
        reversed.add (ColourPoint (colours[i].position, colours[colours.size() - i - 1].colour));
    }

    colours = reversed;
}
juce::ColourGradient flipped()
{
    juce::ColourGradient flipped = *this;
    flipped.flip();

    return flipped;
}
juce::ColourGradient reversed()
{
    juce::ColourGradient reversed = *this;
    reversed.reverse();

    return reversed;
}

#2

I’d like to see ColourGradient improved so that the interpolation operation from point to another goes through a function instead of being simply linear.

This way we could have gamma curves, also saw tooths and cool stuff like that.


#3

Ah, that would be really interesting!

Curious as to how the best way to do that would be… Perhaps each ColourPoint could contain an instance of a new class titled GradientFormula to tell juce::Graphics how to draw the gradient between ColourPoints… And to create our own gradient type we would create a class that inherits GradientFormula, and fill a method of some sort.


#4

Sure, though you could already generate any shape you want by using an algorithm to insert points into the ColourGradient object. In fact it’s arguably better to keep that kind of stuff out of the class itself and implement them as free-standing functions.


#5

To avoid polluting your class with various features, I take it.


#6

Yes. The single-responsibility principle, etc.


#7

Fair enough.


#8

Not really, because the result would not be resolution-independent. The current implementation of ColourGradient::createLookupTable() calculates the smallest number of entries required for the resulting lookup table to have accuracy to 1/256th of a colour component. The assumption is that the interpolation transfer function is linear.


#9

Ideally, ColourGradient would be an abstract interface with the existing implementation moved into a subclass LinearColourGradient. Then everything discussed in this thread can happen: non linear transfer functions, different methods for computing the number of entries in the lookup table, and a more robust interface for manipulating colour control points.


#10

Not going to happen. The class is designed for copy-by-value semantics, it can’t have subclasses.


#11

It would have to become a handle that wraps an abstract, reference counted, and dynamically allocated object, much like Image.