title: CGGradient: Drawing a linear gradient on an angle
body: <p>I am trying to draw a linear CGGradient on an angle. Because "CGContextDrawLinearGradientWithAngle()" does not exist, I am trying to use CGContextDrawLinearGradient(CGContextRef, CGGradientRef, CGPoint startPoint, CGPoint endPoint, CGGradientDrawingOptions).</p>
  
  <p>With that in mind, I need to convert an angle (degrees) into a starting point and an ending point. I would like to mimic NSGradient's drawInBezierPath:angle. (As a part of AppKit, NSGradient is sadly not available to iOS developers.) Fortunately, the documentation tells us how to <a href="https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/NSGradient_class/Reference/Reference.html#//apple_ref/occ/instm/NSGradient/drawInRect%3aangle%3a" rel="noreferrer">get the starting gradient</a>:</p>
  
  <pre><code>- (CGPoint)startingPointForAngle:(CGFloat)angle rect:(CGRect)rect { 
      CGPoint point = CGPointZero;
      if (angle &lt; 90.0f)
          point = CGPointMake(CGRectGetMinX(rect), CGRectGetMaxY(rect));
      else if (angle &lt; 180.0f)
          point = CGPointMake(CGRectGetMaxX(rect), CGRectGetMaxY(rect));
      else if (angle &lt; 270.0f)
          point = CGPointMake(CGRectGetMaxX(rect), CGRectGetMinY(rect));
      else
          point = CGPointMake(CGRectGetMinX(rect), CGRectGetMinY(rect));
  
      return point;
  }
  </code></pre>
  
  <p>Unfortunately, the documentation does not tell us how to get the ending point. (Using either the height or the width of the rect as the distance is only sufficient for certain angles.) <a href="http://www.zahniser.net/~russell/computer/index.php?title=Angle%20and%20Coordinates" rel="noreferrer">Several sites out there</a> tells us how we can find the ending point. Unfortunately, the distance needs to be known before I can compute the ending point. Yet the ending point needs to be computed to get the distance. There is clearly more to it, as NSGradient seems to have it figured out. </p>
  
  <pre><code>- (CGPoint)endingPointForAngle:(CGFloat)angle rect:(CGRect)rect startingPoint:(CGPoint)startingPoint {
      //http://www.zahniser.net/~russell/computer/index.php?title=Angle%20and%20Coordinates
      //(x + distance * cos(a), y + distance * sin(a))
      CGFloat angleInRadians = (CGFloat)M_PI/180.0f * angle;
      CGFloat distance = ????????;
      CGPoint point = CGPointMake(startingPoint.x + distance * cosf(angleInRadians), startingPoint.y + distance * sinf(angleInRadians));
      return point;
  }
  
  CGPoint startingGradientPoint = [self startingPointForAngle:self.fillGradientAngle rect:rect];
  CGPoint endingGradientPoint = [self endingPointForAngle:self.fillGradientAngle rect:rect startingPoint:startingGradientPoint];
  CGContextDrawLinearGradient(graphicsContext, self.fillGradient, startingGradientPoint, endingGradientPoint, 0);
  </code></pre>
  
  <p>Any ideas.</p>