How to draw conic gradient?

Here you go. It’s not the fastest implementation as it uses an intermediate image and fills every pixel but should work ok:

//==============================================================================
/** Fills and angle gradient.
    The gradient will start at -Pi radians (or 90 degrees to the left) and continue all the way round.
*/
inline void fillAngleGradient (Graphics& g, const ColourGradient& cg, Rectangle<int> bounds)
{
    Image img (Image::ARGB, bounds.getWidth(), bounds.getHeight(), false);
    const Image::BitmapData destData (img, Image::BitmapData::writeOnly);

    const float cx = (float) bounds.getCentreX();
    const float cy = (float) bounds.getCentreY();

    const float scale = (1.0f / (2.0f * MathConstants<float>::pi));

    HeapBlock<PixelARGB> lookup;
    const int numEntries = cg.createLookupTable (AffineTransform(), lookup);

    for (int y = 0; y < bounds.getHeight(); ++y)
    {
        for (int x = 0; x < bounds.getWidth(); ++x)
        {
            const float angleRadians = FastMathApproximations::atan2 (bounds.getY() + y - cy, bounds.getX() + x - cx);
            const float a = scale * (angleRadians + MathConstants<float>::pi);
            const int index = roundToInt (a * (numEntries - 1));
            jassert (isPositiveAndNotGreaterThan (a, 1.0f));
            jassert (isPositiveAndBelow (index, numEntries));

            destData.setPixelColour (x, y, lookup[index]);
        }
    }

    g.drawImageAt (img, bounds.getX(), bounds.getY());
}
9 Likes