My blog has been moved to ariya.ofilabs.com.

Monday, June 06, 2011

rectangular gradient

Thorsten Zachmann, from Calligra (and previously KOffice) fame, asked me once on how to draw a different kind of gradient: a rectangular one. While Qt itself has built-in supports for linear, radial, and conical gradient types, apparently for office apps we may need more than that. In short, the goal is creating the following:

It turns out that this is not so difficult at all, about 50 lines of code. Check it out at the usual X2 repository and find it under graphics/rectgradient.

Basically it boils down to a two-step process, as illustrated below. The first one is easy, just create a linear gradient from the center going north and south. The second one is similar, but now we are going east and west and clip it to two triangles. Once we combined both, we get the rectangular gradient.

Have fun with the gradient!

8 comments:

knue said...

While this is correct from a mathematical point of view, it looks odd, however. Have a look a the first image. It looks like if the diagonals are different. This effect emerges because we are humans and our cognition works like this. There is work around to minimize this effect. Just do a google search. Perhaps you can take a look.

mikelima said...

If this works for you, go ahead...
But I think a more general form would have a "fading point" like the one for the radial gradient. You can still render it, using four linear gradients, though...
Or four transformed version of the same gradient.

It would be a useful addition to Qt and or Svg, as it would improve interoperability/rendering of other kind of documents.

Ariya Hidayat said...

@Knue: Any visually-corrected implementation is outside the scope of this example. However, being a curious man, I would be interested in finding out what kind of effect did you refer to?

Ariya Hidayat said...

@mikelima: Could be you kind as to elaborate what you did mean by "fading point"?

Anonymous said...

@Aria: Sure.

What I mean is the gradient could interpolate from one color at the border of the rectangle to another in an arbitrary point within the rectangle.

Ariya Hidayat said...

If you check the code, it's fairly easy to set that "arbitrary point". I kept the code simple (this is example after all) and set that point as the center of the rectangle. It's already using that four linear gradient approach, so it's a matter of translating it properly.

pebbie said...

why creating 2 images? why not use 2 1D arrays each represents horizontal and vertical gradient, like this:

hgrad dimension: image width
vgrad dimension: image height

foreach pixel in target image, written pixel value is minimum of hgrad[x] and vgrad[y]

Ariya Hidayat said...

@pebbie: Pixel-based approach should easily. The reason for re-using Qt's built-in gradient support is to make it possible to run it on other the raster engine, e.g. on your OpenGL application.