【问题标题】:Gradient for the curved line, drawn with quartz 2d曲线的渐变,用石英 2d 绘制
【发布时间】:2014-02-26 13:21:25
【问题描述】:

我正在使用立方贝塞尔曲线(UIBezierPath 类)绘制一条曲线,该曲线使用两个控制点位于我们点的对角。我需要使用取决于 y 值的渐变来绘制它。感谢您的帮助,因为现在我已经坚持了下来。这是我的代码:

CGPoint point1 = CGPointMake(50, 70);
CGPoint point2 = CGPointMake(70, 75);

bool drawACurve;
drawACurve = true;

float tangent;
if ((int)(point2.y - point1.y) == 0) {
    tangent = 0.0f;
    drawACurve = false;
}
else {
    tangent = (point2.x - point1.x) / (point2.y - point1.y);
}

UIBezierPath *path1 = [UIBezierPath bezierPath];
[path1 setLineWidth:1.0];
[[UIColor blueColor] set];

if (drawACurve)
{
    // Draw a curve
    float factor;
    CGPoint controlPoint1;
    CGPoint controlPoint2;

    factor = MAX_FACTOR;

    if (fabs(tangent) >= 1.0 && fabs(tangent) < TANGENT_BOUND_FOR_LINE)
        factor = MIN_FACTOR;

    if (tangent > 0) {
        controlPoint1 = CGPointMake(point2.x - point2.x * factor, point1.y - point1.y * factor);
        controlPoint2 = CGPointMake(point1.x + point1.x * factor, point2.y + point2.y * factor);
    }
    else {
        // For tangent less than zero
        controlPoint1 = CGPointMake(point2.x - point2.x * factor, point1.y + point1.y * factor);
        controlPoint2 = CGPointMake(point1.x + point1.x * factor, point2.y - point2.y * factor);
    }

    [path1 moveToPoint:point1];
    [path1 addCurveToPoint:point2 controlPoint1:controlPoint1 controlPoint2:controlPoint2];
}
else
{
    // Draw a line
    [path1 moveToPoint:point1];
    [path1 addLineToPoint:point2];
}

[path1 stroke];

【问题讨论】:

    标签: ios objective-c gradient quartz-2d bezier


    【解决方案1】:

    如果我的理解正确,这里有一个解决方案。我使用简单的蓝到绿渐变绘制了路径,在 y 方向上有所不同。我已经对代码进行了注释以解释它在做什么。

    CGPoint point1 = CGPointMake(50, 70);
    CGPoint point2 = CGPointMake(70, 75);
    
    bool drawACurve;
    drawACurve = true;
    
    float tangent;
    if ((int)(point2.y - point1.y) == 0) {
        tangent = 0.0f;
        drawACurve = false;
    }
    else {
        tangent = (point2.x - point1.x) / (point2.y - point1.y);
    }
    
    UIBezierPath *path1 = [UIBezierPath bezierPath];
    [path1 setLineWidth:1.0];
    
    if (drawACurve)
    {
        // Draw a curve
        float factor;
        CGPoint controlPoint1;
        CGPoint controlPoint2;
    
        factor = MAX_FACTOR;
    
        if (fabs(tangent) >= 1.0 && fabs(tangent) < TANGENT_BOUND_FOR_LINE)
            factor = MIN_FACTOR;
    
        if (tangent > 0) {
            controlPoint1 = CGPointMake(point2.x - point2.x * factor, point1.y - point1.y * factor);
            controlPoint2 = CGPointMake(point1.x + point1.x * factor, point2.y + point2.y * factor);
        }
        else {
            // For tangent less than zero
            controlPoint1 = CGPointMake(point2.x - point2.x * factor, point1.y + point1.y * factor);
            controlPoint2 = CGPointMake(point1.x + point1.x * factor, point2.y - point2.y * factor);
        }
    
        [path1 moveToPoint:point1];
        [path1 addCurveToPoint:point2 controlPoint1:controlPoint1 controlPoint2:controlPoint2];
    }
    else
    {
        // Draw a line
        [path1 moveToPoint:point1];
        [path1 addLineToPoint:point2];
    }
    
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); // You could choose another color space.
    CGFloat locations[2] = {0.f, 1.f}; // Locations for a simple linear gradient with a start color and end color at either end of the drawing points.
    CGFloat colorComponents[8] = {0.f, 0.f, 1.f, 1.f, // Start blue
                                    0.f, 1.f, 0.f, 1.f}; // Finish green
    CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, colorComponents, locations, 2); // Create the gradient. Can also be created with CGGradientCreateWithColors().
    CGColorSpaceRelease(colorSpace);
    
    CGPathRef outerPath = CGPathCreateCopyByStrokingPath(path1.CGPath, NULL, path1.lineWidth, path1.lineCapStyle, path1.lineJoinStyle, path1.miterLimit); // This function creates a path that outlines another, using various stroke options. Pass in the stroke options from path1.
    // From the docs: The new path is created so that filling the new path draws the same pixels as stroking the original path.
    
    CGContextRef context = UIGraphicsGetCurrentContext(); // Get the current graphics context.
    CGContextAddPath(context, outerPath); // Add the new path.
    CGContextClip(context); // Clip the context to the path.
    
    CGRect boundingBox = CGPathGetBoundingBox(outerPath); // I'm just doing this to get the startPoint and endPoint for the gradient drawing.
    CGPathRelease(outerPath);
    CGPoint startPoint = boundingBox.origin;
    CGPoint endPoint = CGPointMake(boundingBox.origin.x, CGRectGetHeight(boundingBox)); // Different from startPoint in y value, as requested.
    
    CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0); // Draw the gradient.
    CGGradientRelease(gradient);
    

    【讨论】:

    • 感谢您的回答,但我在屏幕上看不到任何东西,它是白色的。
    • 为我工作,@Oleg。您是否在视图的drawRect 方法中执行所有这些操作?
    • 是的。 - (void)drawRect:(CGRect)rect
    • 您是否对我发布的代码进行了任何更改?也许是渐变绘制的起点和终点?
    • 能否请您将此文本从可滚动区域复制到您的程序中,看看是否有效?谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多