Ios 在一组给定点之间绘制贝塞尔曲线
在iOS应用程序中,绘制通过一组给定点的贝塞尔曲线的最佳方法是什么?您可以轻松地通过谷歌搜索一些如何在web上创建贝塞尔曲线的示例。我发现这个简短的例子 例如,可以使用以下代码段为创建闭合贝塞尔曲线:Ios 在一组给定点之间绘制贝塞尔曲线,ios,bezier,uibezierpath,bemsimplelinegraph,Ios,Bezier,Uibezierpath,Bemsimplelinegraph,在iOS应用程序中,绘制通过一组给定点的贝塞尔曲线的最佳方法是什么?您可以轻松地通过谷歌搜索一些如何在web上创建贝塞尔曲线的示例。我发现这个简短的例子 例如,可以使用以下代码段为创建闭合贝塞尔曲线: UIBezierPath* path = [UIBezierPath bezierPath]; [path moveToPoint:pt1]; [path addLineToPoint:pt2]; [path addLineToPoint:pt3]; [path closePath]; 我希
UIBezierPath* path = [UIBezierPath bezierPath];
[path moveToPoint:pt1];
[path addLineToPoint:pt2];
[path addLineToPoint:pt3];
[path 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];
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];
bezierPath.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];
我知道这可能已经晚了,但只适合那些正在寻找正确答案的人。而不是使用addLineToPoint绘制直线。可以使用addCurveToPoint绘制曲线。e、 g
[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=最后一个控制点,x=当前点,x-20;y=当前_点_y
您可能需要使用其他值,而不是20,因为曲线的线段宽度可能不同。使用
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];
例如,可以通过查看(有关更多信息,请参见此处:)来实现更通用的方法。这里我提取了一种通过给定的点列表绘制贝塞尔曲线的方法 头文件(BezierLine.h):
#导入
#进口
#进口
@接口BezierLine:NSObject
/*
在给定上下文上绘制贝塞尔曲线
带点:CGPoint值数组
*/
-(void)drawBezierCurveInContext:(CGContextRef)带有点的上下文:(NSArray*)点线条颜色:(UIColor*)颜色线条宽度:(CGFloat)线条宽度;
@结束
实现(BezierLine.m):
#导入“BezierLine.h”
@实现BezierLine
-(void)drawBezierCurveInContext:(CGContextRef)带有点的上下文:(NSArray*)点线条颜色:(UIColor*)颜色线条宽度:(CGFloat)线条宽度{
如果(点数<2)返回;
CG1点;
CG2点;
//线
UIBezierPath*行=[UIBezierPath bezierPath];
cgp0点;
CGP1点;
CGP2点;
cgp3点;
CGFloat张力Bezier1=0.3;
CGFloat张力Bezier2=0.3;
CGPoint-previousPoint1;
CGPoint-previousPoint2;
[line moveToPoint:[[points objectAtIndex:0]CGPointValue]];
对于(int i=0;i0){//第一行出现异常,因为没有上一个点
p0=先前的点1;
如果(p2.y-p1.y==p1.y-p0.y)张力Bezier1=0;
}否则{
张力Bezier1=0;
p0=p1;
}
如果(iMaxTenstence)tensionBezier1=MaxTenstence;
如果(tensionBezier2>MaxTenstence)tensionBezier2=MaxTenstence;
//第一控制点
CP1=CGPointMake(p1.x+(p2.x-p1.x)/3,
p1.y-(p1.y-p2.y)/3-(p0.y-p1.y)*张力Bezier1;
//第二控制点
CP2=CGPointMake(p1.x+2*(p2.x-p1.x)/3,
(p1.y-2*(p1.y-p2.y)/3+(p2.y-p3.y)*张力Bezier2);
[线路添加曲线点:p2控制点1:CP1控制点2:CP2];
上一点1=p1;
上一点2=p2;
}
CGContextSetAllowsAntialiasing(上下文,是);
CGContextSetStrokeColorWithColor(上下文,color.CGColor);
CGContextSetLineWidth(上下文,线宽);
CGContextAddPath(context,line.CGPath);
CGContextDrawPath(上下文,kCGPathStroke);
}
@结束
例如,您可以使用UIGraphicsBeginImageContext创建图像上下文,并使用UIGraphicsGetCurrentContext()检索上下文
否则,您可能需要更改代码并将结果路径指定给CALayer,然后将其添加到UIView
希望这能有所帮助。请在投票否决之前分享你的问题重新评分代码。bechara-kheye gechilo:p这只是画了一条直线,没有回答问题。
#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
#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