2012-02-22 29 views
4

我想繪製角度上的線性CGGradient。由於「CGContextDrawLinearGradientWithAngle()」不存在,我試圖使用CGContextDrawLinearGradient(CGContextRef,CGGradientRef,CGPoint startPoint,CGPoint endPoint,CGGradientDrawingOptions)。CGGradient:在角度上繪製線性漸變

考慮到這一點,我需要將角度(度)轉換爲起點和終點。我想模仿NSGradient的drawInBezierPath:angle。 (作爲了AppKit的一部分,NSGradient可悲的是不提供給iOS開發)。幸運的是,文件告訴我們如何get the starting gradient

- (CGPoint)startingPointForAngle:(CGFloat)angle rect:(CGRect)rect { 
    CGPoint point = CGPointZero; 
    if (angle < 90.0f) 
     point = CGPointMake(CGRectGetMinX(rect), CGRectGetMaxY(rect)); 
    else if (angle < 180.0f) 
     point = CGPointMake(CGRectGetMaxX(rect), CGRectGetMaxY(rect)); 
    else if (angle < 270.0f) 
     point = CGPointMake(CGRectGetMaxX(rect), CGRectGetMinY(rect)); 
    else 
     point = CGPointMake(CGRectGetMinX(rect), CGRectGetMinY(rect)); 

    return point; 
} 

不幸的是,文件沒有告訴我們如何得到終點。 (使用矩形的高度或寬度作爲距離僅適用於某些角度。)Several sites out there告訴我們如何找到終點。不幸的是,在計算結束點之前,需要知道距離。然而,需要計算終點來獲得距離。 NSGradient似乎已經想通了,這顯然更多。

- (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); 

任何想法。

回答

0

我不是100%確定這個漸變的東西是如何工作的,但是從你所寫的內容來看,我假設你基本上只是想從起點開始直到它碰到矩形的一側。

如果是這種情況,你只需要做一些三角函數。讓我們調用距離x和角度a。

介於0度和45度:寬度= xcos(A),使X =寬度/餘弦的(a)

之間45和90輩分:高度= xsin(A),使X =高度/ SIN(a)中

在90度和135度之間,我們已經搬到了新角落。這裏x =高度/ cos(a-90)。

之間135和180×=寬度/ SIN(A-90)

之間180和225我們已經再次移動角。這裏x =寬度/ cos(a-180)。

225和270之間x =高度/ sin(a-180)

最後一個角落!之間270和315 X =高度/ SIN(A-270)

最後之間315和360 X =寬度/餘弦(A-270)

其中的一些可能簡化,但其最容易想到的從左下角開始向右指向,並逆時針旋轉,這就是在你的起點計算中出現的情況。

1

我正在處理同樣的問題,用一個不同的方式,我使用中心點和和角度,並擴大左右側,找到它的邊緣點,我的問題是會有白色如果天使沒有指向任何軸,並且繪圖選項的功能提供了「kCGGradientDrawsBeforeStartLocation或kCGGradientDrawsAfterEndLocation」,那麼看起來一邊是空的。

但事實證明,我可以結合使用兩個選項「|」,所以問題就迎刃而解了,這裏是我的代碼:

CGGradientRef grRef = CGGradientCreateWithColors(colorSpace, (__bridge CFArrayRef)gradient.colorArray, NULL); 
CGFloat degree = angle * M_PI/180; 
CGPoint center = CGPointMake(width/2, height/2); 
CGPoint startPoint = CGPointMake(center.x - cos (degree) * width/2, center.y - sin(degree) * height/2); 
CGPoint endPoint = CGPointMake(center.x + cos (degree) * width/2, center.y + sin(degree) * height/2); 

NSLog(@"start point:%@ \n, end point: %@",NSStringFromCGPoint(startPoint),NSStringFromCGPoint(endPoint)); 

CGContextDrawLinearGradient(gradientContext, grRef, startPoint, endPoint, kCGGradientDrawsBeforeStartLocation|kCGGradientDrawsAfterEndLocation);