如何繪製如圖所示的圓弧,假設我有一個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? –