沿着简单的三次贝塞尔曲线找到一个点,一个给定的距离.(在iPhone上!)

Fat*_*tie 16 iphone bezier ipad

想象一下,你有一个完全正常的四点贝塞尔曲线(两点和两个控制点)使用curveToPoint创建:controlPoint1:controlPoint2:在你的cocoa应用程序中:

简单的三次贝塞尔曲线例子
你如何沿曲线找到点(和切线)?


后来:对于基于Michal的答案的完整,简化的解决方案,请点击:
找到立方贝塞尔曲线上的点的切线(在iPhone上)

只需复制并粘贴代码:https://stackoverflow.com/a/31317254/294884

Mic*_*hal 29

计算位置背后有一些简单的数学,你可以在讨论Bézier曲线的每篇论文中阅读它,甚至在维基百科上.无论如何,我可以告诉每个遇到麻烦的人在代码中实际实现它,所以我写了这个样本UIView,因为它可能是让你入门的最简单的方法.

#import "MBBezierView.h"

CGFloat bezierInterpolation(CGFloat t, CGFloat a, CGFloat b, CGFloat c, CGFloat d) {
    CGFloat t2 = t * t;
    CGFloat t3 = t2 * t;
    return a + (-a * 3 + t * (3 * a - a * t)) * t
    + (3 * b + t * (-6 * b + b * 3 * t)) * t
    + (c * 3 - c * 3 * t) * t2
    + d * t3;
}

@implementation MBBezierView

- (void)drawRect:(CGRect)rect {
    CGPoint p1, p2, p3, p4;
    p1 = CGPointMake(30, rect.size.height * 0.33);
    p2 = CGPointMake(CGRectGetMidX(rect), CGRectGetMinY(rect));
    p3 = CGPointMake(CGRectGetMidX(rect), CGRectGetMaxY(rect));
    p4 = CGPointMake(-30 + CGRectGetMaxX(rect), rect.size.height * 0.66);

    [[UIColor blackColor] set];
    [[UIBezierPath bezierPathWithRect:rect] fill];

    [[UIColor redColor] setStroke];

    UIBezierPath *bezierPath = [[[UIBezierPath alloc] init] autorelease];   
    [bezierPath moveToPoint:p1];
    [bezierPath addCurveToPoint:p4 controlPoint1:p2 controlPoint2:p3];
    [bezierPath stroke];

    [[UIColor brownColor] setStroke];
    for (CGFloat t = 0.0; t <= 1.00001; t += 0.05) {
        CGPoint point = CGPointMake(bezierInterpolation(t, p1.x, p2.x, p3.x, p4.x), bezierInterpolation(t, p1.y, p2.y, p3.y, p4.y));
        UIBezierPath *pointPath = [UIBezierPath bezierPathWithArcCenter:point radius:5 startAngle:0 endAngle:2*M_PI clockwise:YES];
        [pointPath stroke];
    }   
}

@end
Run Code Online (Sandbox Code Playgroud)

这就是我得到的:

替代文字

  • @Joe Blow:这真的是你想要的吗?你说你想要一个沿着曲线的距离为D的点.Michal,如果我错了,请纠正我,但是你的代码只是在不同参数值下评估曲线,这与长度不同.如您所见,这些点在峰值中更靠近在一起,并且在曲线中间更加分开. (3认同)