我要绘制的形状等使用在IOS芯图形附加图像英寸 这可能吗。 如果可能,请提供的示例代码。
我想在形状上至少3的颜色渐变。
我要绘制的形状等使用在IOS芯图形附加图像英寸 这可能吗。 如果可能,请提供的示例代码。
我想在形状上至少3的颜色渐变。
CGContext
: 使用+[UIBezierPath bezierPathWithArcCenter:radius:startAngle:endAngle:clockwise:]
创建包含一个半圆弧形的路径。 然后使用CGPathCreateCopyByStrokingPath
创建电弧周围封闭的形状。 使用CGContextAddPath
这个封闭的形状添加到您的上下文的路径,然后使用CGContextClip
到剪辑区域设置为厚弧。
使用CGGradientCreateWithColors
创建CGGradient
与彩虹的颜色。 使用CGContextDrawLinearGradient
与渐变填充裁剪区域。
CALayer
: 创建CAGradientLayer
。 该层的设置colors
属性的颜色的彩虹。 设置图层的startPoint
(0,0)和层的endPoint
到(1,0)。
创建CAShapeLayer
并将其设置为渐变图层的蒙版。 使用+[UIBezierPath bezierPathWithArcCenter:radius:startAngle:endAngle:clockwise:]
和CGPathCreateCopyByStrokingPath
创建包围厚弧的路径,并且设置这个路径作为形状层的path
。
渐变不自然地沿着路径绘制。 你要模仿它。 该代码使用NSBezierPath是NSView和CGContext上,但它不应该是很难将它移植到iOS。
我做了梯形的组件。
这里是一个NSView绘制梯度的drawRect:
@implementation grad
-(void)drawRect:(NSRect)dirtyRect {
[[NSColor whiteColor]set];
NSRectFill([self bounds]);
float dim = MIN(self.bounds.size.width, self.bounds.size.height);
int subdiv=512;
float r=dim/4;
float R=dim/2;
float halfinteriorPerim = M_PI*r;
float halfexteriorPerim = M_PI*R;
float smallBase= halfinteriorPerim/subdiv;
float largeBase= halfexteriorPerim/subdiv;
NSBezierPath * cell = [NSBezierPath bezierPath];
[cell moveToPoint:NSMakePoint(- smallBase/2, r)];
[cell lineToPoint:NSMakePoint(+ smallBase/2, r)];
[cell lineToPoint:NSMakePoint( largeBase /2 , R)];
[cell lineToPoint:NSMakePoint(-largeBase /2, R)];
[cell closePath];
float incr = M_PI / subdiv;
CGContextRef ctx = [[NSGraphicsContext currentContext] graphicsPort];
CGContextTranslateCTM(ctx, +self.bounds.size.width/2, +self.bounds.size.height/2);
CGContextScaleCTM(ctx, 0.9, 0.9);
CGContextRotateCTM(ctx, M_PI/2);
CGContextRotateCTM(ctx,-incr/2);
for (int i=0;i<subdiv;i++) {
// replace this color with a color extracted from your gradient object
[[NSColor colorWithCalibratedHue:(float)i/subdiv saturation:1 brightness:1 alpha:1] set];
[cell fill];
[cell stroke];
CGContextRotateCTM(ctx, -incr);
}
}
这看起来像这样,具有的各种组合subdiv
和r
内半径)中,在不同的尺度。
此版本使用Objective-C的块的颜色和轮廓功能。 只是在一个块传递返回内半径的功能,外半径和颜色为0和1的其他参数之间的任何数量的起始角度,结束角度,细分,中心的数目,并用于调试目的的规模,和一个CGContextRef。
#import "GradientView.h"
@implementation GradientView
typedef void (^voidBlock)(void);
typedef float (^floatfloatBlock)(float);
typedef UIColor * (^floatColorBlock)(float);
-(CGPoint) pointForTrapezoidWithAngle:(float)a andRadius:(float)r forCenter:(CGPoint)p{
return CGPointMake(p.x + r*cos(a), p.y + r*sin(a));
}
-(void)drawGradientInContext:(CGContextRef)ctx startingAngle:(float)a endingAngle:(float)b intRadius:(floatfloatBlock)intRadiusBlock outRadius:(floatfloatBlock)outRadiusBlock withGradientBlock:(floatColorBlock)colorBlock withSubdiv:(int)subdivCount withCenter:(CGPoint)center withScale:(float)scale
{
float angleDelta = (b-a)/subdivCount;
float fractionDelta = 1.0/subdivCount;
CGPoint p0,p1,p2,p3, p4,p5;
float currentAngle=a;
p4=p0 = [self pointForTrapezoidWithAngle:currentAngle andRadius:intRadiusBlock(0) forCenter:center];
p5=p3 = [self pointForTrapezoidWithAngle:currentAngle andRadius:outRadiusBlock(0) forCenter:center];
CGMutablePathRef innerEnveloppe=CGPathCreateMutable(),
outerEnveloppe=CGPathCreateMutable();
CGPathMoveToPoint(outerEnveloppe, 0, p3.x, p3.y);
CGPathMoveToPoint(innerEnveloppe, 0, p0.x, p0.y);
CGContextSaveGState(ctx);
CGContextSetLineWidth(ctx, 1);
for (int i=0;i<subdivCount;i++)
{
float fraction = (float)i/subdivCount;
currentAngle=a+fraction*(b-a);
CGMutablePathRef trapezoid = CGPathCreateMutable();
p1 = [self pointForTrapezoidWithAngle:currentAngle+angleDelta andRadius:intRadiusBlock(fraction+fractionDelta) forCenter:center];
p2 = [self pointForTrapezoidWithAngle:currentAngle+angleDelta andRadius:outRadiusBlock(fraction+fractionDelta) forCenter:center];
CGPathMoveToPoint(trapezoid, 0, p0.x, p0.y);
CGPathAddLineToPoint(trapezoid, 0, p1.x, p1.y);
CGPathAddLineToPoint(trapezoid, 0, p2.x, p2.y);
CGPathAddLineToPoint(trapezoid, 0, p3.x, p3.y);
CGPathCloseSubpath(trapezoid);
CGPoint centerofTrapezoid = CGPointMake((p0.x+p1.x+p2.x+p3.x)/4, (p0.y+p1.y+p2.y+p3.y)/4);
CGAffineTransform t = CGAffineTransformMakeTranslation(-centerofTrapezoid.x, -centerofTrapezoid.y);
CGAffineTransform s = CGAffineTransformMakeScale(scale, scale);
CGAffineTransform concat = CGAffineTransformConcat(t, CGAffineTransformConcat(s, CGAffineTransformInvert(t)));
CGPathRef scaledPath = CGPathCreateCopyByTransformingPath(trapezoid, &concat);
CGContextAddPath(ctx, scaledPath);
CGContextSetFillColorWithColor(ctx,colorBlock(fraction).CGColor);
CGContextSetStrokeColorWithColor(ctx, colorBlock(fraction).CGColor);
CGContextSetMiterLimit(ctx, 0);
CGContextDrawPath(ctx, kCGPathFillStroke);
CGPathRelease(trapezoid);
p0=p1;
p3=p2;
CGPathAddLineToPoint(outerEnveloppe, 0, p3.x, p3.y);
CGPathAddLineToPoint(innerEnveloppe, 0, p0.x, p0.y);
}
CGContextSetLineWidth(ctx, 10);
CGContextSetLineJoin(ctx, kCGLineJoinRound);
CGContextSetStrokeColorWithColor(ctx, [UIColor blackColor].CGColor);
CGContextAddPath(ctx, outerEnveloppe);
CGContextAddPath(ctx, innerEnveloppe);
CGContextMoveToPoint(ctx, p0.x, p0.y);
CGContextAddLineToPoint(ctx, p3.x, p3.y);
CGContextMoveToPoint(ctx, p4.x, p4.y);
CGContextAddLineToPoint(ctx, p5.x, p5.y);
CGContextStrokePath(ctx);
}
-(void)drawRect:(CGRect)rect {
CGContextRef ctx = UIGraphicsGetCurrentContext();
[[UIColor whiteColor] set];
UIRectFill(self.bounds);
CGRect r = self.bounds;
r=CGRectInset(r, 60, 60);
if (r.size.width > r.size.height)
r.size.width=r.size.height;
else r.size.height=r.size.width;
float radius=r.size.width/2;
[self drawGradientInContext:ctx startingAngle:M_PI/16 endingAngle:2*M_PI-M_PI/16 intRadius:^float(float f) {
// return 0*f + radius/2*(1-f);
return 200+10*sin(M_PI*2*f*7);
// return 50+sqrtf(f)*200;
// return radius/2;
} outRadius:^float(float f) {
// return radius *f + radius/2*(1-f);
return radius;
// return 300+10*sin(M_PI*2*f*17);
} withGradientBlock:^UIColor *(float f) {
// return [UIColor colorWithHue:f saturation:1 brightness:1 alpha:1];
float sr=90, sg=54, sb=255;
float er=218, eg=0, eb=255;
return [UIColor colorWithRed:(f*sr+(1-f)*er)/255. green:(f*sg+(1-f)*eg)/255. blue:(f*sb+(1-f)*eb)/255. alpha:1];
} withSubdiv:256 withCenter:CGPointMake(CGRectGetMidX(r), CGRectGetMidY(r)) withScale:1];
}
@end
例子:
由于iOS 8的,最简单的和快捷的方式来绘制圆形梯度是使用核心绘图过滤器。 内核是链接到评论这个答案 ,但由于搞清楚如何实际使用,我花了一段时间,我会在这里发布的整个过程。
从本质上讲,核心图片滤波器是对输入图像的每个像素执行的小片段着色器。 虽然他们的目的是过滤的图像,你可以使用它们只是简单地忽略你的过滤器内核的输入像素值来生成图像。
下面的代码来生成虚拟图像作为输入来使用,然后施加一个自定义CI内核它使一个圆形梯度。
// 1 - generate a dummy image of the required size
UIGraphicsBeginImageContextWithOptions(CGSizeMake(512.0, 256.0), NO, [[UIScreen mainScreen] scale]);
CIImage *dummyImage = [CIImage imageWithCGImage:UIGraphicsGetImageFromCurrentImageContext().CGImage];
// 2 - define the kernel algorithm
NSString *kernelString = @"kernel vec4 circularGradientKernel(__color startColor, __color endColor, vec2 center, float innerR, float outerR) { \n"
" vec2 point = destCoord() - center;"
" float rsq = point.x * point.x + point.y * point.y;"
" float theta = mod(atan(point.y, point.x), radians(360.0));"
" return (rsq > innerR*innerR && rsq < outerR*outerR) ? mix(startColor, endColor, theta/radians(360.0)*2.0) : vec4(0.0, 0.0, 0.0, 1.0);"
"}";
// 3 - initialize a Core Image context and the filter kernel
CIContext *context = [CIContext contextWithOptions:nil];
CIColorKernel *kernel = [CIColorKernel kernelWithString:kernelString];
// 4 - argument array, corresponding to the first line of the kernel string
NSArray *args = @[ [CIColor colorWithRed:1.0 green:0.0 blue:0.0],
[CIColor colorWithRed:0.0 green:0.0 blue:1.0],
[CIVector vectorWithCGPoint:CGPointMake(CGRectGetMidX(dummyImage.extent),CGRectGetMinY(dummyImage.extent))],
[NSNumber numberWithFloat:250.0],
[NSNumber numberWithFloat:500.0]];
// 5 - apply the kernel to our dummy image, and convert the result to a UIImage
CIImage *ciOutputImage = [kernel applyWithExtent:dummyImage.extent arguments:args];
CGImageRef cgOutput = [context createCGImage:ciOutputImage fromRect:ciOutputImage.extent];
UIImage *gradientImage = [UIImage imageWithCGImage:cgOutput];
CGImageRelease(cgOutput);
输出看起来是这样的:
的颜色和中心点被传递在打包为CIColor
S和CIVector
s,并且内圆和外圆的半径给定为浮动。 如果你想在其他参数传给你当然可以修改参数列表。
这种方法甚至不够快,使用动画,但如果你想这样做,请确保您使用相同的上下文对每一帧,创建和撕裂下来是一个性能瓶颈。 只要确保你的动画参数是输入参数,并遍历步骤4和5。
另外,不要忘记调用CGImageRelease
底,否则你就会有内存泄漏。
我用安东尼的答案,并调整它的iOS:
-(void)drawRect:(CGRect)rect {
// http://stackoverflow.com/a/12775798/129202
CGContextRef context = UIGraphicsGetCurrentContext();
[[UIColor whiteColor] set]; //[[NSColor whiteColor]set];
UIRectFill([self bounds]);
float dim = MIN(self.bounds.size.width, self.bounds.size.height);
int subdiv=512;
float r=dim/4;
float R=dim/2;
float halfinteriorPerim = M_PI*r;
float halfexteriorPerim = M_PI*R;
float smallBase= halfinteriorPerim/subdiv;
float largeBase= halfexteriorPerim/subdiv;
UIBezierPath * cell = [UIBezierPath bezierPath];
[cell moveToPoint:CGPointMake(- smallBase/2, r)];
[cell addLineToPoint:CGPointMake(+ smallBase/2, r)];
[cell addLineToPoint:CGPointMake( largeBase /2 , R)];
[cell addLineToPoint:CGPointMake(-largeBase /2, R)];
[cell closePath];
float incr = M_PI / subdiv;
//CGContextRef ctx = [[NSGraphicsContext currentContext] graphicsPort];
CGContextTranslateCTM(context, +self.bounds.size.width/2, +self.bounds.size.height/2);
CGContextScaleCTM(context, 0.9, 0.9);
CGContextRotateCTM(context, M_PI/2);
CGContextRotateCTM(context,-incr/2);
for (int i=0;i<subdiv;i++) {
// replace this color with a color extracted from your gradient object
[[UIColor colorWithHue:(float)i/subdiv saturation:1 brightness:1 alpha:1] set];
[cell fill];
[cell stroke];
CGContextRotateCTM(context, -incr);
}
}
作为另一个答案,我发现这一点: https://github.com/paiv/AngleGradientLayer
我尝试过了,而且运作良好。 我还没有研究的实施。 我不认为我需要。 :-)
代码在这一点:
//
// The MIT License (MIT)
//
// Copyright (C) 2012 Pavel Ivashkov
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
//
// AngleGradientLayer.m
// paiv
//
// Created by Pavel Ivashkov on 2012-02-12.
//
#import "AngleGradientLayer.h"
#if __has_feature(objc_arc)
#define BRIDGE_CAST(T) (__bridge T)
#else
#define BRIDGE_CAST(T) (T)
#endif
#define byte unsigned char
#define F2CC(x) ((byte)(255 * x))
#define RGBAF(r,g,b,a) (F2CC(r) << 24 | F2CC(g) << 16 | F2CC(b) << 8 | F2CC(a))
#define RGBA(r,g,b,a) ((byte)r << 24 | (byte)g << 16 | (byte)b << 8 | (byte)a)
#define RGBA_R(c) ((uint)c >> 24 & 255)
#define RGBA_G(c) ((uint)c >> 16 & 255)
#define RGBA_B(c) ((uint)c >> 8 & 255)
#define RGBA_A(c) ((uint)c >> 0 & 255)
@interface AngleGradientLayer()
- (CGImageRef)newImageGradientInRect:(CGRect)rect;
@end
static void angleGradient(byte* data, int w, int h, int* colors, int colorCount, float* locations, int locationCount);
@implementation AngleGradientLayer
- (id)init
{
if (!(self = [super init]))
return nil;
self.needsDisplayOnBoundsChange = YES;
return self;
}
#if !__has_feature(objc_arc)
- (void)dealloc
{
[_colors release];
[_locations release];
[super dealloc];
}
#endif
- (void)drawInContext:(CGContextRef)ctx
{
CGContextSetFillColorWithColor(ctx, self.backgroundColor);
CGRect rect = CGContextGetClipBoundingBox(ctx);
CGContextFillRect(ctx, rect);
CGImageRef img = [self newImageGradientInRect:rect];
CGContextDrawImage(ctx, rect, img);
CGImageRelease(img);
}
- (CGImageRef)newImageGradientInRect:(CGRect)rect
{
return [[self class] newImageGradientInRect:rect colors:self.colors locations:self.locations];
}
+ (CGImageRef)newImageGradientInRect:(CGRect)rect colors:(NSArray *)colors locations:(NSArray *)locations
{
int w = CGRectGetWidth(rect);
int h = CGRectGetHeight(rect);
int bitsPerComponent = 8;
int bpp = 4 * bitsPerComponent / 8;
int byteCount = w * h * bpp;
int colorCount = (int)colors.count;
int locationCount = (int)locations.count;
int* cols = NULL;
float* locs = NULL;
if (colorCount > 0) {
cols = calloc(colorCount, bpp);
int *p = cols;
for (id cg in colors) {
CGColorRef c = BRIDGE_CAST(CGColorRef)cg;
float r, g, b, a;
size_t n = CGColorGetNumberOfComponents(c);
const CGFloat *comps = CGColorGetComponents(c);
if (comps == NULL) {
*p++ = 0;
continue;
}
r = comps[0];
if (n >= 4) {
g = comps[1];
b = comps[2];
a = comps[3];
}
else {
g = b = r;
a = comps[1];
}
*p++ = RGBAF(r, g, b, a);
}
}
if (locationCount > 0 && locationCount == colorCount) {
locs = calloc(locationCount, sizeof(locs[0]));
float *p = locs;
for (NSNumber *n in locations) {
*p++ = [n floatValue];
}
}
byte* data = malloc(byteCount);
angleGradient(data, w, h, cols, colorCount, locs, locationCount);
if (cols) free(cols);
if (locs) free(locs);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGBitmapInfo bitmapInfo = kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Little;
CGContextRef ctx = CGBitmapContextCreate(data, w, h, bitsPerComponent, w * bpp, colorSpace, bitmapInfo);
CGColorSpaceRelease(colorSpace);
CGImageRef img = CGBitmapContextCreateImage(ctx);
CGContextRelease(ctx);
free(data);
return img;
}
@end
static inline byte blerp(byte a, byte b, float w)
{
return a + w * (b - a);
}
static inline int lerp(int a, int b, float w)
{
return RGBA(blerp(RGBA_R(a), RGBA_R(b), w),
blerp(RGBA_G(a), RGBA_G(b), w),
blerp(RGBA_B(a), RGBA_B(b), w),
blerp(RGBA_A(a), RGBA_A(b), w));
}
static inline int multiplyByAlpha(int c)
{
float a = RGBA_A(c) / 255.0;
return RGBA((byte)(RGBA_R(c) * a),
(byte)(RGBA_G(c) * a),
(byte)(RGBA_B(c) * a),
RGBA_A(c));
}
void angleGradient(byte* data, int w, int h, int* colors, int colorCount, float* locations, int locationCount)
{
if (colorCount < 1) return;
if (locationCount > 0 && locationCount != colorCount) return;
int* p = (int*)data;
float centerX = (float)w / 2;
float centerY = (float)h / 2;
for (int y = 0; y < h; y++)
for (int x = 0; x < w; x++) {
float dirX = x - centerX;
float dirY = y - centerY;
float angle = atan2f(dirY, dirX);
if (dirY < 0) angle += 2 * M_PI;
angle /= 2 * M_PI;
int index = 0, nextIndex = 0;
float t = 0;
if (locationCount > 0) {
for (index = locationCount - 1; index >= 0; index--) {
if (angle >= locations[index]) {
break;
}
}
if (index >= locationCount) index = locationCount - 1;
nextIndex = index + 1;
if (nextIndex >= locationCount) nextIndex = locationCount - 1;
float ld = locations[nextIndex] - locations[index];
t = ld <= 0 ? 0 : (angle - locations[index]) / ld;
}
else {
t = angle * (colorCount - 1);
index = t;
t -= index;
nextIndex = index + 1;
if (nextIndex >= colorCount) nextIndex = colorCount - 1;
}
int lc = colors[index];
int rc = colors[nextIndex];
int color = lerp(lc, rc, t);
color = multiplyByAlpha(color);
*p++ = color;
}
}
我花了很长时间寻找如何做到这一点,太,所以我想我会发布我落得这样做的方式。 原来两个答案都在良好的回答这个问题:
绘制从一个圆或圆环段
对于我而言,我只用图纸和答案的梯度部分。 该结构看起来或多或少像这样...
CGContextRef context = UIGraphicsGetCurrentcontext();
CGFloat arcStartAngle = M_PI;
CGFloat arcEndAngle = 2 * M_PI;
CGPoint startPoint = CGPointMake(...);
CGPoint endPoint = CGPointMake(...);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGFloat colors[] =
{
1.0, 0.0, 0.0, 1.0, //RGBA values (so red to green in this case)
0.0, 1.0, 0.0, 1.0
};
CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, colors, NULL, 2);
//Where the 2 is for the number of color components. You can have more colors throughout //your gradient by adding to the colors[] array, and changing the components value.
CGColorSpaceRelease(colorSpace);
//Now for the arc part...
CGMutablePathRef arc = CGPathCreateMutable();
CGPathMoveToPoint(arc, NULL, startPoint.x, startPoint.y);
//Here, the CGPoint self.arcCenter is the point around which the arc is placed, so maybe the
//middle of your view. self.radius is the distance between this center point and the arc.
CGPathAddArc(arc, NULL, self.arcCenter.x, self.arcCenter.y, self.radius,
arcStartAngle, arcEndAngle, YES);
//This essentially draws along the path in an arc shape
CGPathRef strokedArc = CGPathCreateCopyByStrokingPath(arc, NULL, 5.0f,
kCGLineCapButt, kCGLineJoinMiter, 10);
CGContextSaveGState(context);
CGContextAddPath(context, strokedArc);
CGContextClip(context);
CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0);
CGContextDrawPath(context, kCGPathFillStroke);
CGGradientRelease(gradient);
CGContextRestoreGState(context);
//This all draws a gradient that is much larger than the arc itself, but using
//CGContextClip, it clips out everything EXCEPT the colors in the arc. Saving and Restoring
//the state allows you to preserve any other drawing going on. If you didn't use these,
//then all other drawing would also be clipped.
我希望这有帮助。 如果有任何不清楚这个,我建议你检查出的问题,以上链接。 这个问题的答案的问题包含我这个答案,多了一些冷静和有用的绘图技巧使用的一切。
我用alecail的答案(的iOS与块),但是,我注意到,它需要一些调整(只是增加了一些CGPathRelease()的- (空)drawGratientInContext:...),因为它使用了太多记忆。 对不起,我会发布这个作为一个评论,但我没有50+的声誉,我必须回答如下所示:
-(void)drawGradientInContext:(CGContextRef)ctx startingAngle:(float)a endingAngle:(float)b intRadius:(floatfloatBlock)intRadiusBlock outRadius:(floatfloatBlock)outRadiusBlock withGradientBlock:(floatColorBlock)colorBlock withSubdiv:(int)subdivCount withCenter:(CGPoint)center withScale:(float)scale
{
float angleDelta = (b-a)/subdivCount;
float fractionDelta = 1.0/subdivCount;
CGPoint p0,p1,p2,p3, p4,p5;
float currentAngle=a;
p4=p0 = [self pointForTrapezoidWithAngle:currentAngle andRadius:intRadiusBlock(0) forCenter:center];
p5=p3 = [self pointForTrapezoidWithAngle:currentAngle andRadius:outRadiusBlock(0) forCenter:center];
CGMutablePathRef innerEnveloppe=CGPathCreateMutable(),
outerEnveloppe=CGPathCreateMutable();
CGPathMoveToPoint(outerEnveloppe, 0, p3.x, p3.y);
CGPathMoveToPoint(innerEnveloppe, 0, p0.x, p0.y);
CGContextSaveGState(ctx);
CGContextSetLineWidth(ctx, 1);
for (int i=0;i<subdivCount;i++)
{
float fraction = (float)i/subdivCount;
currentAngle=a+fraction*(b-a);
CGMutablePathRef trapezoid = CGPathCreateMutable();
p1 = [self pointForTrapezoidWithAngle:currentAngle+angleDelta andRadius:intRadiusBlock(fraction+fractionDelta) forCenter:center];
p2 = [self pointForTrapezoidWithAngle:currentAngle+angleDelta andRadius:outRadiusBlock(fraction+fractionDelta) forCenter:center];
CGPathMoveToPoint(trapezoid, 0, p0.x, p0.y);
CGPathAddLineToPoint(trapezoid, 0, p1.x, p1.y);
CGPathAddLineToPoint(trapezoid, 0, p2.x, p2.y);
CGPathAddLineToPoint(trapezoid, 0, p3.x, p3.y);
CGPathCloseSubpath(trapezoid);
CGPoint centerofTrapezoid = CGPointMake((p0.x+p1.x+p2.x+p3.x)/4, (p0.y+p1.y+p2.y+p3.y)/4);
CGAffineTransform t = CGAffineTransformMakeTranslation(-centerofTrapezoid.x, -centerofTrapezoid.y);
CGAffineTransform s = CGAffineTransformMakeScale(scale, scale);
CGAffineTransform concat = CGAffineTransformConcat(t, CGAffineTransformConcat(s, CGAffineTransformInvert(t)));
CGPathRef scaledPath = CGPathCreateCopyByTransformingPath(trapezoid, &concat);
CGContextAddPath(ctx, scaledPath);
CGContextSetFillColorWithColor(ctx,colorBlock(fraction).CGColor);
CGContextSetStrokeColorWithColor(ctx, colorBlock(fraction).CGColor);
CGContextSetMiterLimit(ctx, 0);
CGContextDrawPath(ctx, kCGPathFillStroke);
p0=p1;
p3=p2;
CGPathAddLineToPoint(outerEnveloppe, 0, p3.x, p3.y);
CGPathAddLineToPoint(innerEnveloppe, 0, p0.x, p0.y);
//Release both CGPathRefs. The original code just released
//trapezoid CG .
CGPathRelease(trapezoid);
CGPathRelease(scaledPath);
}
//stroke width
CGContextSetLineWidth(ctx, 0.0001);
CGContextSetLineJoin(ctx, kCGLineJoinRound);
CGContextSetStrokeColorWithColor(ctx, [UIColor blackColor].CGColor);
CGContextAddPath(ctx, outerEnveloppe);
CGContextAddPath(ctx, innerEnveloppe);
CGContextMoveToPoint(ctx, p0.x, p0.y);
CGContextAddLineToPoint(ctx, p3.x, p3.y);
CGContextMoveToPoint(ctx, p4.x, p4.y);
CGContextAddLineToPoint(ctx, p5.x, p5.y);
CGContextStrokePath(ctx);
//Release CGPathRefs
CGPathRelease(innerEnveloppe);
CGPathRelease(outerEnveloppe);
}