曲线的渐变,用石英2d绘制

时间:2014-02-26 13:21:25

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

我使用立方贝塞尔曲线(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];

1 个答案:

答案 0 :(得分: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);