gpt4 book ai didi

iphone - 在 iOS 中使用核心图形绘制带渐变的外半圆?

转载 作者:IT王子 更新时间:2023-10-29 08:07:06 26 4
gpt4 key购买 nike

我想在 iOS 中使用核心图形绘制一个形状,如附图所示。这可能吗。如果可能,请提供示例代码。 enter image description here

我希望在形状上至少有 3 种颜色渐变。

最佳答案

渐变不会自然地沿着路径绘制。你必须模拟它。该代码使用了 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);
}
}

这看起来像这样,具有 subdivr(内部半径)的各种组合,并且具有不同的比例。

Gradient along a circle

带 block 的新版本,iOS 就绪

此版本使用 Objective-C block 来实现颜色和轮廓函数。只需在一个 block 中传递一个函数,该函数返回 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

例子:

Curved gradient 1

Curved gradient 2

关于iphone - 在 iOS 中使用核心图形绘制带渐变的外半圆?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11783114/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com