Silver Solution


#1

Here’s my solution to the Silver Challenge. The only changes are to drawRect: in TouchDrawView.m. I called an audible and decided to draw the x-y axes. Comments appreciated.

-(void)drawRect:(CGRect)rect
{
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetLineWidth(context, 1.0);
    CGContextSetLineCap(context, kCGLineCapRound);
    CGFloat dash[] = {5,3};
    CGContextSetLineDash(context, 0, dash, 2);
    [[UIColor redColor] set];
    
    //Attempting to create x-y axis
    float width = [[UIScreen mainScreen] bounds].size.width;
    float height = [[UIScreen mainScreen] bounds].size.height;
    
    //creat x-axis
    CGContextMoveToPoint(context, 0, height/2.0);
    CGContextAddLineToPoint(context, width, height/2.0);
    CGContextStrokePath(context);
    
    //creat y-axis
    CGContextMoveToPoint(context, width/2.0, 0);
    CGContextAddLineToPoint(context, width/2.0, height);
    CGContextStrokePath(context);
    
    CGContextSetLineWidth(context, 10.0);
    CGContextSetLineCap(context, kCGLineCapRound);
    
    for (Line *line in completeLines)
    {
        //Determine angle using cos(theta) = adjacent/hypot
        //There will be four colors associated with 45 deg increments b/w 0 & 180
        //The colors are red, green, blue, yellow
        //begin => x1,x2
        //end   => x2,y2
        double adjacent = [line end].x - [line begin].x;
        double hypotenuse = sqrt(pow([line end].x - [line begin].x, 2) + pow([line end].y - [line begin].y, 2));
        double angleInRadians = acos(adjacent/hypotenuse);
        int angleInDegrees = angleInRadians*360/(2*3.14);
        
        if (angleInDegrees > 135)
        {
            [[UIColor yellowColor] set];
        }
        else if (angleInDegrees >90)
        {
            [[UIColor blueColor] set];
        }
        else if (angleInDegrees > 45)
        {
            [[UIColor greenColor] set];
        }
        else
        {
            [[UIColor redColor] set];
        }
        CGContextMoveToPoint(context, [line begin].x, [line begin].y);
        CGContextAddLineToPoint(context, [line end].x, [line end].y);
        CGContextStrokePath(context);
    }

//Rest of code remains unchanged

#2

You should use UIColor’s -colorWithHue instead. That small change will make it look way cooler (if you are one of those colorful kinds anyway).

colorWithHue documentation: xcdoc://ios/documentation/UIKit/Referen … rence.html

I’m using arctan to find the angle (in rads) and then converting to degrees (* 180 / M_PI ), as described in the following article. The if operation after it is just to fix the value in the 3rd and 4th quadrants, as they would return negative in the arctan equation. hyperphysics.phy-astr.gsu.edu/hb … ig.html#c2

My function inside DrawRect:


    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetLineWidth(context, 20.0);
    CGContextSetLineCap(context, kCGLineCapRound);
    
    for (Line *line in [[LineStore sharedStore] allLines]) {
        CGContextMoveToPoint(context, [line begin].x, [line begin].y);
        CGContextAddLineToPoint(context, [line end].x, [line end].y);
        
        float angle = atan2f( ([line begin].y - [line end].y), ([line end].x - [line begin].x) ) * 180/M_PI;
        
        if ((([line end].x - [line begin].x) < 0 && ([line begin].y - [line end].y) < 0) ||
            (([line end].x - [line begin].x) >= 0 && ([line begin].y - [line end].y) < 0) ) {
            angle = angle + 360;
        }

//        NSLog(@"Angle is: %f", angle);
        [[UIColor colorWithHue:angle/360 saturation:1.0 brightness:1.0 alpha:1.0] setStroke];
        
        CGContextStrokePath(context);
    }

#3

Gilmar,

Do you have a color reference you use for the hue etc. convention? I mean I kinda know what RGB values produce. Not so much with h s b.

Jeff


#4

@physics90,
Looks like he’s giving saturation, brightness, and alpha all a value of 1, while he changes the “hue” to be the angle of the line.

        float angle = atan2f( ([line begin].y - [line end].y), ([line end].x - [line begin].x) ) * 180/M_PI;
        
        if ((([line end].x - [line begin].x) < 0 && ([line begin].y - [line end].y) < 0) ||
            (([line end].x - [line begin].x) >= 0 && ([line begin].y - [line end].y) < 0) ) {
            angle = angle + 360;
        }

//        NSLog(@"Angle is: %f", angle);
        [[UIColor colorWithHue:angle/360 saturation:1.0 brightness:1.0 alpha:1.0] setStroke];

#5

[quote=“physics90”]Gilmar,
Do you have a color reference you use for the hue etc. convention? I mean I kinda know what RGB values produce. Not so much with h s b.
Jeff[/quote]

Hi Jeff,

Here’s a real quick explanation from the book “HTML & CSS Design and Build Websites” by Jon Duckett. I hope it helps.

The great thing of HSB in this particular case is the fact that I can obtain completely different colors by changing only 1 ‘variable’ (hue), so I don’t need to generate random numbers like I would have to do with RGB values.

I like to think of it as a color wheel with a pointer in the middle (like a clock) that allows for a very quick selection of colors. In fact, in web, HTML5 uses HSB with values from 0 to 360 just like that, but since Cocoa touch uses values from 0 to 1, I’m dividing the angle by 360 to respect that.

And just like larryb said, I’m keeping saturation and brightness to their maximum values, just because I want those shockingly bright colors.

Cheers

Gilmar


#6

Thanks, everyone. Actually, what I’m looking for is how do you determine what color is hue=0.23 or hue=0.57? Trial and error, a web page that shows the different colors, or by using the hub slider bars in xcode or another software?

Interestingly, I thought about creating a simple app that just allows me to change h,s,b to determine the values I want.


#7

From what I’ve seen it looks like it just follows the ROY G BIV with red at the 0 point.