It’s been long since I last posted about my GSOC work, so today I’ll be writing about how I achieved the color picker. There are several points that comes to the mind when we thing about the colorpicker.

- How to achieve the gradient color selection area
- Use a pre-rendered image ?
- Generate using computer algorithm ? If what are the appropriate opengl calls?

- What is the algorithm for picking the color from the location ?
- Use opengl methods to pick the pixel from the point where the user touches ?
- Or use some algorithmic technique to determine where the user is touching local to the gradient and then calculate the appropriate RGB values

There is a humongous list of resources available for Color pickers especially AJAX based, but my problem was different, I wanted a Quarter Circle Color Picker 🙂 , nowhere in the internet did i find one single open-source quarter circle color pickers, but hey no pain no gain :), so I set out to create a Opengl rendered quarter circle color picker with algorithmic based color picking.

**1. Rendering the Gradient Circle**

So my first goal was to create a opengl rendered quarter circle, well its very easy to generate a single color circles in opengl like the ones that I have used in my previous widgets, Rendering a gradient one is a very hard task. I know that opengl allows to blend colors by specifying different colors at different vertices of a polygon, but how can one do the same in a circle ?!!, circle has no vertex edges.

A Color Blended Triangle

I did not find any way to get around this problem using Circle render, so the alternative solution was to render thin triangles and arrange it in the form of a fan, and when i looked around the net for this one, to my surprise there was one opening call to make such a polygon using triangle fan.

def drawPartialCircle(pos=(0,0), radius=100):
with gx_begin(GL_TRIANGLE_FAN):
glColor3f(0,0,1)
glVertex2f(0,0)
for angle in range (90,185,5):
glColor3f(sin(radians(angle-90))*sqrt(2),cos(radians(angle-90))*sqrt(2),0)
glVertex2f(int(cos(radians(angle))*radius),int(sin(radians(angle))*radius))

So in the above algorithm i’ve chosen the angle range from 90 to 185 because i want it to appear at the bottom right corner. So what the algoritm does it,

- It generates 5 degree triangles to form a quater circle.
- The center of the circle is blue so the other two edges of the two radii will be red and green respectively.
- The mid way of the circumference must be yellow that is RGB =>(1,1,0) , so to we know that only at 45 degrees sin 45 = cos 45.
- sin 45 = 1/sqrt(2), so to obtain 1 at the center we multiply it by sqrt(2), so we get (1,1,0) at the center.

Opengl rendered Quarter Circle

If you have any queries regarding this algo, feel free to comment.

**2. Calculating color at the touch point**

I used the similar sine cos formula to calculate the RGB values, The R and G values varies according to the angle made by the line joining the center and the touch point with the horizontal line. Whereas the blue value is a function of the distance touch point from the center. So here goes the algorithm

def calculate_color(self):
b = 1-self.point_distance/self.size[0]
r = (sin(radians(self.point_angle))-b)*sqrt(2)
g = (cos(radians(self.point_angle))-b)*sqrt(2)

where self.size[0] is the radius of the circle.

**3. Hue and Saturation**

As you can see in the rendered quarter circle above there is no range of black nor white, so this posed a new challenge to use a slider to make a hue saturation variation, HSV[Hue, Saturation, Value] is an alernative representation of RGB color space, something similar to Rectangular to Polar coordinates conversion.

HSV Representation

Since I need to vary the color from White>>Color>>Black, the variation has to be done in two steps

- White >> Color variation, which is nothing but variation of the Saturation, here saturation = 0 implies White
- Color >> Black which is variation of the Value field

Thomas (My mentor) pointed me to this really nifty function in core python **rgb_to_hsv **and **hsv_to_rgb **, which converts between the colorspaces with ease. So I divide the slider into two portions lower limit to middle value for saturation, middle value to upper limit for Value. I chose to take 2 as the maximum range of the slider, so it varies from 0 to 2, and middle i get 1. I developed the following algorithm.

value = rgb_to_hsv(self.slider.slider_color[0],self.slider.slider_color[1],self.slider.slider_color[2])

h,s,v = value[0],value[1],value[2]

if self.slider._value <= 1.0:
s = self.slider._value
else:
v = 2-self.slider._value
self.slider.slider_color = hsv_to_rgb(h,s,v)
[/sourcecode]
Overall this entire widget was very complex to build, but I got to learn alot from this tiny project. If you have queries regarding any of the algorithm that I developed, or if you have suggestions of better algorithm, or anything at all feel free to comment :), it will definitely help me make this project better