Рисование кривой Безье между множеством заданных точек

Как лучше всего нарисовать кривую Безье в приложении для iOS, которая проходит через набор заданных точек

Ответы на вопрос(6)

BEMSimpleLineGraph GitHub Project (см. здесь для получения дополнительной информации:bemsimplelinegraph). Здесь я извлек метод для рисования кривой Безье через заданный список точек.

Заголовочный файл (BezierLine.h):

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <CoreGraphics/CoreGraphics.h>

@interface BezierLine : NSObject

/*
 Draws a bezier curved line on the given context
 with points: Array of CGPoint values
 */
-(void) drawBezierCurveInContext:(CGContextRef)context withPoints:(NSArray*)points lineColor:(UIColor*)color lineWidth:(CGFloat)lineWidth;

@end

Реализация (BezierLine.m):

#import "BezierLine.h"

@implementation BezierLine

-(void) drawBezierCurveInContext:(CGContextRef)context withPoints:(NSArray*)points lineColor:(UIColor*)color lineWidth:(CGFloat)lineWidth {
    if (points.count < 2) return;

    CGPoint CP1;
    CGPoint CP2;

    // LINE
    UIBezierPath *line = [UIBezierPath bezierPath];

    CGPoint p0;
    CGPoint p1;
    CGPoint p2;
    CGPoint p3;
    CGFloat tensionBezier1 = 0.3;
    CGFloat tensionBezier2 = 0.3;

    CGPoint previousPoint1;
    CGPoint previousPoint2;

    [line moveToPoint:[[points objectAtIndex:0] CGPointValue]];

    for (int i = 0; i < points.count - 1; i++) {
        p1 = [[points objectAtIndex:i] CGPointValue];
        p2 = [[points objectAtIndex:i + 1] CGPointValue];

        const CGFloat maxTension = 1.0f / 3.0f;
        tensionBezier1 = maxTension;
        tensionBezier2 = maxTension;

        if (i > 0) { // Exception for first line because there is no previous point
            p0 = previousPoint1;
            if (p2.y - p1.y == p1.y - p0.y) tensionBezier1 = 0;
        } else {
            tensionBezier1 = 0;
            p0 = p1;
        }

        if (i < points.count - 2) { // Exception for last line because there is no next point
            p3 = [[points objectAtIndex:i + 2] CGPointValue];
            if (p3.y - p2.y == p2.y - p1.y) tensionBezier2 = 0;
        } else {
            p3 = p2;
            tensionBezier2 = 0;
        }

        // The tension should never exceed 0.3
        if (tensionBezier1 > maxTension) tensionBezier1 = maxTension;
        if (tensionBezier2 > maxTension) tensionBezier2 = maxTension;

        // First control point
        CP1 = CGPointMake(p1.x + (p2.x - p1.x)/3,
                          p1.y - (p1.y - p2.y)/3 - (p0.y - p1.y)*tensionBezier1);

        // Second control point
        CP2 = CGPointMake(p1.x + 2*(p2.x - p1.x)/3,
                          (p1.y - 2*(p1.y - p2.y)/3) + (p2.y - p3.y)*tensionBezier2);


        [line addCurveToPoint:p2 controlPoint1:CP1 controlPoint2:CP2];

        previousPoint1 = p1;
        previousPoint2 = p2;
    }

    CGContextSetAllowsAntialiasing(context, YES);
    CGContextSetStrokeColorWithColor(context, color.CGColor);
    CGContextSetLineWidth(context, lineWidth);
    CGContextAddPath(context, line.CGPath);
    CGContextDrawPath(context, kCGPathStroke);
}


@end

Вы можете использовать его, например, создавая контекст изображения с помощью UIGraphicsBeginImageContext и извлекая контекст с помощью UIGraphicsGetCurrentContext ().

В противном случае вы можете изменить код и назначить полученный путь к CALayer и добавить его в UIView.

Надеюсь это поможет.

используяCGPointFromString метод:

 NSArray *pointArray = @[@"{3.0,2.5}",@"{100.0,30.2}", @"{100.0,200.0}", @"{3.0,200.0}"];

// draw the path
UIBezierPath *aPath = [UIBezierPath bezierPath];
for (NSString *pointString in pointArray) {
    if ([pointArray indexOfObject:pointString] == 0)
        [aPath moveToPoint:CGPointFromString(pointString)];
    else
        [aPath addLineToPoint:CGPointFromString(pointString)];
}
[aPath closePath];
UIBezierPath *aPath = [UIBezierPath bezierPath];

// Set the starting point of the shape.
[aPath moveToPoint:CGPointMake(100.0, 0.0)];

// Draw the lines.
[aPath addLineToPoint:CGPointMake(200.0, 40.0)];
[aPath addLineToPoint:CGPointMake(160, 140)];
[aPath addLineToPoint:CGPointMake(40.0, 140)];
[aPath addLineToPoint:CGPointMake(0.0, 40.0)];
[aPath closePath];
 FiddleMeRagged02 февр. 2016 г., 00:34
Это просто рисует прямые линии и не отвечает на вопрос.

что это может быть поздно, но только для тех, кто ищет правильный ответ. Вместо использования addLineToPoint для рисования прямой линии. Вы можете использовать addCurveToPoint, чтобы нарисовать кривую. например

[bezierPath moveToPoint:CGPointMake(0, 0)];
[bezierPath addCurveToPoint:CGPointMake(40, 100) 
              controlPoint1:CGPointMake(20, 0) 
              controlPoint2:CGPointMake(20, 100)];
[bezierPath addCurveToPoint:CGPointMake(80, 50) 
              controlPoint1:CGPointMake(60, 100) 
              controlPoint2:CGPointMake(60, 50)];

// and you may don't want to close the path
// [bezierPath closePath];

Это действительно зависит от вас, чтобы выбрать контрольные точки кривой. Я просто использую x = last_point_x + 20; y = last_point_y для контрольной точки один, а x = current_point_x - 20; y = current_point_y;

и вы можете использовать другое значение вместо 20, поскольку у вас может быть другая ширина сегмента кривой.

попробуйте это.

UIImageView *waterLevel = [[UIImageView alloc] initWithFrame:CGRectMake(0,0,200,200)];
UIGraphicsBeginImageContext(waterLevel.frame.size);
[waterLevel.image drawAtPoint:CGPointZero];
//define BezierPath
UIBezierPath *bezierPath = [UIBezierPath bezierPath];


// Set the starting point of the shape.
[bezierPath moveToPoint:CGPointMake(0, 0)];

[bezierPath addLineToPoint:CGPointMake(waterLevel.frame.size.width, 0)];
[bezierPath addLineToPoint:CGPointMake(waterLevel.frame.size.width, waterLevel.frame.size.height)];
[bezierPath addLineToPoint:CGPointMake(0, waterLevel.frame.size.height)];
[bezierPath closePath];

be,zierPath.lineWidth = 15;
//set the stoke color
[[UIColor blackColor] setStroke];
//draw the path
[bezierPath stroke];

// Add to the current Graphic context
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextAddPath(context,bezierPath.CGPath);
waterLevel.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

[self.view addSubview:waterLevel];
 Maniac One09 янв. 2014 г., 15:12
бечара - хейе гечило: P
 Milan Kamilya27 нояб. 2013 г., 06:11
Пожалуйста, поделитесь своей проблемой, обновляя код, прежде чем понизить его.

как создать кривую Безье в Интернете. Я нашел это короткимрепетит В качестве примера.

Вы можете создать близкую кривую Безье, например, для со следующим фрагментом кода:

UIBezierPath* path = [UIBezierPath bezierPath];

[path moveToPoint:pt1];
[path addLineToPoint:pt2];
[path addLineToPoint:pt3];

[path closePath];

Я надеюсь, что это поможет в качестве отправной точки.

Ваш ответ на вопрос