gpt4 book ai didi

iOS quartz 绘图应用程序

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:41:10 24 4
gpt4 key购买 nike

更新:正确的绘制矩形方法如下所示

- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();

if(layer == nil)
{
float scale = [UIScreen mainScreen].scale;
CGRect bounds = CGRectMake(0, 0, rect.size.width *scale, rect.size.height *scale);
layer = CGLayerCreateWithContext(context, bounds.size, NULL);
layerContext = CGLayerGetContext(layer);
CGContextScaleCTM(layerContext, scale, scale);
viewRect = CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height);
}

UIBezierPath *bezierPath = path.bezierPath;
CGContextAddPath(layerContext, bezierPath.CGPath);
CGContextSetLineWidth(layerContext, path.width);
CGContextSetStrokeColorWithColor(layerContext, path.color.CGColor);
CGContextSetLineCap(layerContext, kCGLineCapRound);
CGContextStrokePath(layerContext);

CGContextDrawLayerInRect(context, viewRect, layer);
self.empty = NO;
}

更新:我已按照建议完成,将路径添加到数组并绘制到 CGLayer,如下所示。但是,当绘制大量路径时,性能确实会降低。我犯了什么错误吗?

    - (void)pan:(UIPanGestureRecognizer *)pan
{
CGPoint velocity = [pan velocityInView:self];

previousPoint2 = previousPoint1;
previousPoint1 = currentPoint;
currentPoint = [pan locationInView:self];

float velocityMagnitude = sqrtf(velocity.x * velocity.x + velocity.y * velocity.y);

float clampedVelocityMagnitude = clamp(VELOCITY_CLAMP_MIN, VELOCITY_CLAMP_MAX, velocityMagnitude);
float normalizedVelocity = (clampedVelocityMagnitude - VELOCITY_CLAMP_MIN) / (VELOCITY_CLAMP_MAX - VELOCITY_CLAMP_MIN);

float lowPassFilterAlpha = STROKE_WIDTH_SMOOTHING;
float newThickness = (STROKE_WIDTH_MAX - STROKE_WIDTH_MIN) * normalizedVelocity + STROKE_WIDTH_MIN;
self.lineWidth = self.lineWidth * lowPassFilterAlpha + newThickness * (1 - lowPassFilterAlpha);

CGPoint mid1 = midPoint(previousPoint1, previousPoint2);
CGPoint mid2 = midPoint(currentPoint, previousPoint1);
CGMutablePathRef subpath = CGPathCreateMutable();
CGPathMoveToPoint(subpath, NULL, mid1.x, mid1.y);
CGPathAddQuadCurveToPoint(subpath, NULL, previousPoint1.x, previousPoint1.y, mid2.x, mid2.y);
CGRect bounds = CGPathGetBoundingBox(subpath);

Path *path = [[Path alloc] init];
path.width = self.lineWidth;
path.color = [UIColor redColor];
path.bezierPath = [UIBezierPath bezierPathWithCGPath:subpath];
[pathArray addObject:path];
CGPathRelease(subpath);

CGRect drawBox = bounds;
drawBox.origin.x -= self.lineWidth * 2.0;
drawBox.origin.y -= self.lineWidth * 2.0;
drawBox.size.width += self.lineWidth * 4.0;
drawBox.size.height += self.lineWidth * 4.0;

[self setNeedsDisplayInRect:drawBox];

if (pan.state == UIGestureRecognizerStateEnded | pan.state == UIGestureRecognizerStateCancelled)
{
self.lineWidth = STROKE_WIDTH_MIN;
}
}

- (void)drawRect:(CGRect)rect {
[self.backgroundColor set];
UIRectFill(rect);

CGContextRef context = UIGraphicsGetCurrentContext();

if(layer == nil)
{
float scale = [UIScreen mainScreen].scale;
CGRect bounds = CGRectMake(0, 0, rect.size.width * scale, rect.size.height * scale);
layer = CGLayerCreateWithContext(context, bounds.size, NULL);
layerContext = CGLayerGetContext(layer);
}

for(int i = 0; i < [pathArray count]; i++)
{
Path *path = [pathArray objectAtIndex:i];
UIBezierPath *bezierPath = path.bezierPath;
CGContextAddPath(layerContext, bezierPath.CGPath);
CGContextSetLineWidth(layerContext, path.width);
CGContextSetStrokeColorWithColor(layerContext, path.color.CGColor);
CGContextSetLineCap(layerContext, kCGLineCapRound);
CGContextStrokePath(layerContext);
}

CGContextDrawLayerAtPoint(context, CGPointZero, layer);

self.empty = NO;
}

我使用下面的代码根据用户平移手势的速度绘制宽度可变的线条。它工作正常,但是当我靠近或越过之前绘制的线条时,它的线条宽度会发生变化以匹配当前手势和线条的速度。请问如何确保绘制的线条保持最初绘制时的粗细?

- (void)pan:(UIPanGestureRecognizer *)pan
{
CGPoint velocity = [pan velocityInView:self];

previousPoint2 = previousPoint1;
previousPoint1 = currentPoint;
currentPoint = [pan locationInView:self];

float velocityMagnitude = sqrtf(velocity.x * velocity.x + velocity.y * velocity.y);

float clampedVelocityMagnitude = clamp(VELOCITY_CLAMP_MIN, VELOCITY_CLAMP_MAX, velocityMagnitude);
float normalizedVelocity = (clampedVelocityMagnitude - VELOCITY_CLAMP_MIN) / (VELOCITY_CLAMP_MAX - VELOCITY_CLAMP_MIN);

float lowPassFilterAlpha = STROKE_WIDTH_SMOOTHING;
float newThickness = (STROKE_WIDTH_MAX - STROKE_WIDTH_MIN) * normalizedVelocity + STROKE_WIDTH_MIN;
self.lineWidth = self.lineWidth * lowPassFilterAlpha + newThickness * (1 - lowPassFilterAlpha);

CGPoint mid1 = midPoint(previousPoint1, previousPoint2);
CGPoint mid2 = midPoint(currentPoint, previousPoint1);
CGMutablePathRef subpath = CGPathCreateMutable();
CGPathMoveToPoint(subpath, NULL, mid1.x, mid1.y);
CGPathAddQuadCurveToPoint(subpath, NULL, previousPoint1.x, previousPoint1.y, mid2.x, mid2.y);
CGRect bounds = CGPathGetBoundingBox(subpath);

CGPathAddPath(path, NULL, subpath);
CGPathRelease(subpath);

CGRect drawBox = bounds;
drawBox.origin.x -= self.lineWidth * 2.0;
drawBox.origin.y -= self.lineWidth * 2.0;
drawBox.size.width += self.lineWidth * 4.0;
drawBox.size.height += self.lineWidth * 4.0;

if (pan.state == UIGestureRecognizerStateEnded | pan.state == UIGestureRecognizerStateCancelled)
{
self.lineWidth = STROKE_WIDTH_MIN;
}
else
{
[self setNeedsDisplayInRect:drawBox];
}
}

- (void)drawRect:(CGRect)rect {
[self.backgroundColor set];
UIRectFill(rect);

CGContextRef context = UIGraphicsGetCurrentContext();

CGContextAddPath(context, path);
CGContextSetLineCap(context, kCGLineCapRound);

CGContextSetLineWidth(context, self.lineWidth);
CGContextSetStrokeColorWithColor(context, self.lineColor.CGColor);

CGContextStrokePath(context);

self.empty = NO;
}

最佳答案

每次线宽变化时,您都需要开始一条新路径。您需要将所有这些路径存储到一个数组(或类似数组)中,并在 drawRect: 时绘制它们中的每一个。叫做。这将在绘制时保持线宽。

当前发生的情况是您始终绘制一条路径,因此您始终要为整条路径重置线宽。只是你的view只能刷新drawBox所以这是您实际看到更新的唯一一点。

添加更多行时性能会变差,因此您可能希望开始考虑使用 CGLayer缓存先前绘制的路径并将图层渲染到 drawRect: 中的上下文中而不是迭代路径。

关于iOS quartz 绘图应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19641203/

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