如何绘制如图所示的圆弧,假设我有一个UIView作为可移动的直线的中点。如何通过3点绘制圆弧
我在CGPoint名lineStartPoint和结束点作为lineEndPoint店线的起点。
可以通过名为movePoint的CGPoint访问移动对象。
在此先感谢您的帮助。
如何绘制如图所示的圆弧,假设我有一个UIView作为可移动的直线的中点。如何通过3点绘制圆弧
我在CGPoint名lineStartPoint和结束点作为lineEndPoint店线的起点。
可以通过名为movePoint的CGPoint访问移动对象。
在此先感谢您的帮助。
下面是一个示例,说明如何计算bezierPathWithArcCenter:radius:startAngle:endAngle:clockwise:
方法所需的参数。
- (void)viewDidLoad {
[super viewDidLoad];
// for example
CGPoint lineStartPoint = {100,100};
CGPoint lineEndPoint = {100,200};
CGPoint movingPoint = {30,150};
CGFloat eps = 1e-5;
CGVector v1 = {movingPoint.x-lineEndPoint.x, movingPoint.y-lineEndPoint.y};
CGFloat dist1 = sqrt(v1.dx*v1.dx + v1.dy*v1.dy);
v1.dx = v1.dx/dist1;
v1.dy = v1.dy/dist1;
CGVector v2 = {movingPoint.x-lineStartPoint.x, movingPoint.y-lineStartPoint.y};
CGFloat dist2 = sqrt(v2.dx*v2.dx + v2.dy*v2.dy);
v2.dx = v2.dx/dist2;
v2.dy = v2.dy/dist2;
CGFloat det = v1.dx*v2.dy - v1.dy*v2.dx;
if (fabs(det) < eps) {
// the three points are collinear
// TODO: draw a line from lineStartPoint to lineEndPoint
return;
}
CGPoint mid1 = {(movingPoint.x+lineEndPoint.x)/2, (movingPoint.y+lineEndPoint.y)/2};
CGPoint mid2 = {(movingPoint.x+lineStartPoint.x)/2, (movingPoint.y+lineStartPoint.y)/2};
CGFloat b1 = v1.dx*mid1.x + v1.dy*mid1.y;
CGFloat b2 = v2.dx*mid2.x + v2.dy*mid2.y;
CGFloat centerX = v2.dy/det*b1 - v1.dy/det*b2;
CGFloat centerY = -v2.dx/det*b1 + v1.dx/det*b2;
CGPoint center = {centerX, centerY};
CGFloat radius = sqrtf((movingPoint.x-center.x)*(movingPoint.x-center.x) + (movingPoint.y-center.y)*(movingPoint.y-center.y));
CGFloat startAngle = atan2f(lineStartPoint.y-center.y, lineStartPoint.x-center.x);
CGFloat movingAngle = atan2f(movingPoint.y-center.y, movingPoint.x-center.x);
CGFloat endAngle = atan2f(lineEndPoint.y-center.y, lineEndPoint.x-center.x);
BOOL isClockwise;
if ((endAngle>startAngle && startAngle<movingAngle && movingAngle<endAngle) ||
(endAngle<startAngle && !(endAngle<movingAngle && movingAngle<startAngle))) {
isClockwise = YES;
} else {
isClockwise = NO;
}
//Show results
CAShapeLayer* startPointLayer = [[CAShapeLayer alloc] init];
startPointLayer.path = [UIBezierPath bezierPathWithArcCenter:lineStartPoint radius:2 startAngle:0 endAngle:2*M_PI clockwise:YES].CGPath;
[self.view.layer addSublayer:startPointLayer];
CAShapeLayer* endPointLayer = [[CAShapeLayer alloc] init];
endPointLayer.path = [UIBezierPath bezierPathWithArcCenter:lineEndPoint radius:2 startAngle:0 endAngle:2*M_PI clockwise:YES].CGPath;
[self.view.layer addSublayer:endPointLayer];
CAShapeLayer* movingPointLayer = [[CAShapeLayer alloc] init];
movingPointLayer.path = [UIBezierPath bezierPathWithArcCenter:movingPoint radius:2 startAngle:0 endAngle:2*M_PI clockwise:YES].CGPath;
[self.view.layer addSublayer:movingPointLayer];
CAShapeLayer* arcLayer = [[CAShapeLayer alloc] init];
[arcLayer setFillColor:[UIColor clearColor].CGColor];
[arcLayer setStrokeColor:[UIColor blueColor].CGColor];
arcLayer.path = [UIBezierPath bezierPathWithArcCenter:center radius:radius startAngle:startAngle endAngle:endAngle clockwise:isClockwise].CGPath;
[self.view.layer addSublayer:arcLayer];
}
伟大的答案,以及我想知道的一件事,如果我想要移动移动点在创建90度对应于startPoint和endPoint的方向?总之,移动点只能在相反方向移动。 –
你可以在这里回答http://stackoverflow.com/questions/37324822/restricting-pan-gesture-to-move-to-90-degree –
我建议将这个问题的标题改为'通过3点画弧' – fabe
你要求在两点之间画一条弧线吗? –
是的,通过中点运动 –
你是否尝试过使用bezierPathWithArcCenter:CGPointMake? –