Conic Gradients?

Hi there,

I am creating some 2D radial meshes, and I am interested in filling them with some smooth conic gradients. What I have come up with so far

for (int i = 0; i < 100; i++) {
mesh.addColor(ofColor(ofMap(sin(i * 0.1), -1, 1, 0, 255),
ofMap(sin(i * 0.11), -1, 1, 0, 255),
ofMap(sin(i * 0.12), -1, 1, 0, 255)));
}

works, but of course I am left with a sharp angle where the first and last point meet. I have come up with somewhat of a solution by essentially cutting out that part of the mesh and manually lerping between the colors, but I know there must be a smoother way.

See image below.

Any help would be greatly appreciated!

Hey @mdof,

The discontinuity can be avoided if the angle at the end of the loop is a multiple of TWO_PI, assuming you start with an angle of 0 at the beginning. So playing around with something like the following should work OK:

    int num = 100;
    float angleStep = TWO_PI / static_cast<float>(num);
    for (int i = 0; i < num; i++)
    {
        float angle = i * angleStep;
        float red = ofMap(sin(angle), -1.f, 1.f, 0.f, 255.f);
        float green = ofMap(sin(angle * 2.0), -1.f, 1.f, 0.f, 255.f);
        float blue = ofMap(sin(angle * 3.0), -1.f, 1.f, 0.f, 255.f);
        mesh.addColor(ofColor(red, green, blue));
    }

Each RGB value in an ofColor is an unsigned char. These values “roll over” at 0 and 255, such that 255 + 1 = 0 and 0 - 1 = 255. So you can get a discontinuity if this happens.

ofNoise (or ofSignedNoise) is really fun to work with and could be used in place of the sine wave. Also, you could try lerping between 2 (or more) colors (or individual RGB values) inside the loop, and as long as you lerp back to the beginning value by the end of the loop and are mindful of the boundaries (0 and 255), you should end up with a continuous gradient. Using std::sort with std::vectors of RGB chars could be a fun way to generate gradients too.

edit: changed TWO+PI (type) to TWO_PI (which is 2 * PI)

1 Like

Wow, thank you so much! This is incredibly helpful! I was going to drive myself crazy trying to figure out the math.

1 Like

If you like using the sine wave, you could try shifting the RGB components out of phase with each other: ie red goes from 0 to TWO_PI, green goes from PI/2 to PI/2, blue goes from PI to PI, etc. Have fun!

1 Like

Thanks Tim, this is great. For some reason my head was completely working outside of trig and the fact that I am, indeed, dealing with circles haha. Much appreciated!