Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to draw a color wheel in objective-c

I am trying to draw a color wheel for an iPhone, but I can't get the gradient to rotate around a point. I am trying to use gradients but objective-c provides a linear gradient, which draws a gradient in a straight line like this: linear gradient

and a radial gradient, which draws the gradient starting at point and radiating out in all directions like this: radial gradient

I want to draw a linear gradient that rotates around a point like this:

colorwheel

like image 212
Ge3ng Avatar asked Feb 24 '11 18:02

Ge3ng


People also ask

How to draw a color wheel in AutoCAD?

Draw the outer circle 8 1⁄2 inches (22 cm) from the center. Move the leg of your drawing compass so it extends 8 1⁄2 inches (22 cm) from the middle of the color wheel and draw the largest circle. [5] This will be the border for your color wheel. You should now have 3 rings for the color wheel that you'll divide into spaces.

How do you make a color wheel in a compass?

Draw the outer circle 8 1⁄2 inches (22 cm) from the center. Move the leg of your drawing compass so it extends 8 1⁄2 inches (22 cm) from the middle of the color wheel and draw the largest circle. This will be the border for your color wheel. You should now have 3 rings for the color wheel that you'll divide into spaces.

How do you find the center of a color wheel?

Lay a ruler horizontally on the center of the square and make a small mark in the middle using a pencil. Then, turn the ruler vertically so it's lined up with your mark and make a small dot in the center. [2] The small dot will be the center of your color wheel. Use a compass to make a small circle 2 1⁄2 inches (6.4 cm) away from the center.

How do you make a 12 color wheel on a graph?

Variation: To make a simple 12-color color wheel, just draw the large outer circle for the color wheel and don't make the smaller circles within it. Make another circle that's 5 1⁄2 inches (14 cm) from the center dot. To create another row for your color wheel, make a slightly larger circle beyond the small one you just made.


1 Answers

The following draws an HSL color wheel in a UIView subclass. It does this by generating a bitmap by computing, for each pixel, the correct color value. This is not exactly what you're trying to do (looks like it's just hue varies in the circle with a constant luminance/saturation), but you should be able to adapt it for your needs.

Note that this may not have optimal performance, but it should get you started. Also, you can use getColorWheelValue() to handle user input (clicks/touches at a given coordinate).

- (void)drawRect:(CGRect)rect {     int dim = self.bounds.size.width; // should always be square.     bitmapData = CFDataCreateMutable(NULL, 0);     CFDataSetLength(bitmapData, dim * dim * 4);     generateColorWheelBitmap(CFDataGetMutableBytePtr(bitmapData), dim, luminance);     UIImage *image = createUIImageWithRGBAData(bitmapData, self.bounds.size.width, self.bounds.size.height);     CFRelease(bitmapData);     [image drawAtPoint:CGPointZero];     [image release]; }  void generateColorWheelBitmap(UInt8 *bitmap, int widthHeight, float l) {     // I think maybe you can do 1/3 of the pie, then do something smart to generate the other two parts, but for now we'll brute force it.     for (int y = 0; y < widthHeight; y++)     {         for (int x = 0; x < widthHeight; x++)         {             float h, s, r, g, b, a;             getColorWheelValue(widthHeight, x, y, &h, &s);             if (s < 1.0)             {                 // Antialias the edge of the circle.                 if (s > 0.99) a = (1.0 - s) * 100;                 else a = 1.0;                  HSL2RGB(h, s, l, &r, &g, &b);             }             else             {                 r = g = b = a = 0.0f;             }              int i = 4 * (x + y * widthHeight);             bitmap[i] = r * 0xff;             bitmap[i+1] = g * 0xff;             bitmap[i+2] = b * 0xff;             bitmap[i+3] = a * 0xff;         }     } }  void getColorWheelValue(int widthHeight, int x, int y, float *outH, float *outS) {     int c = widthHeight / 2;     float dx = (float)(x - c) / c;     float dy = (float)(y - c) / c;     float d = sqrtf((float)(dx*dx + dy*dy));     *outS = d;     *outH = acosf((float)dx / d) / M_PI / 2.0f;     if (dy < 0) *outH = 1.0 - *outH; }  UIImage *createUIImageWithRGBAData(CFDataRef data, int width, int height) {     CGDataProviderRef dataProvider = CGDataProviderCreateWithCFData(data);     CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();     CGImageRef imageRef = CGImageCreate(width, height, 8, 32, width * 4, colorSpace, kCGImageAlphaLast, dataProvider, NULL, 0, kCGRenderingIntentDefault);     UIImage *image = [[UIImage alloc] initWithCGImage:imageRef];     CGDataProviderRelease(dataProvider);     CGColorSpaceRelease(colorSpace);     CGImageRelease(imageRef);     return image; }  // Adapted from Apple sample code.  See http://en.wikipedia.org/wiki/HSV_color_space#Comparison_of_HSL_and_HSV void HSL2RGB(float h, float s, float l, float* outR, float* outG, float* outB) {     float temp1, temp2;     float temp[3];     int i;      // Check for saturation. If there isn't any just return the luminance value for each, which results in gray.     if(s == 0.0)     {         *outR = l;         *outG = l;         *outB = l;         return;     }      // Test for luminance and compute temporary values based on luminance and saturation      if(l < 0.5)         temp2 = l * (1.0 + s);     else         temp2 = l + s - l * s;     temp1 = 2.0 * l - temp2;      // Compute intermediate values based on hue     temp[0] = h + 1.0 / 3.0;     temp[1] = h;     temp[2] = h - 1.0 / 3.0;      for(i = 0; i < 3; ++i)     {         // Adjust the range         if(temp[i] < 0.0)             temp[i] += 1.0;         if(temp[i] > 1.0)             temp[i] -= 1.0;           if(6.0 * temp[i] < 1.0)             temp[i] = temp1 + (temp2 - temp1) * 6.0 * temp[i];         else {             if(2.0 * temp[i] < 1.0)                 temp[i] = temp2;             else {                 if(3.0 * temp[i] < 2.0)                     temp[i] = temp1 + (temp2 - temp1) * ((2.0 / 3.0) - temp[i]) * 6.0;                 else                     temp[i] = temp1;             }         }     }      // Assign temporary values to R, G, B     *outR = temp[0];     *outG = temp[1];     *outB = temp[2]; } 
like image 87
Daniel Dickison Avatar answered Sep 19 '22 14:09

Daniel Dickison