回答
曲线的正切就是它的导数。参数方程米哈尔用途:
P(t) = (1 - t)^3 * P0 + 3t(1-t)^2 * P1 + 3t^2 (1-t) * P2 + t^3 * P3
应该有
dP(t)/dt = -3(1-t)^2 * P0 + 3(1-t)^2 * P1 - 6t(1-t) * P1 - 3t^2 * P2 + 6t(1-t) * P2 + 3t^2 * P3
衍生物其中,顺便说一句,似乎是错在你前面的问题。我相信你在那里使用斜率为二次贝塞尔曲线,而不是立方。
从那里开始,执行计算的C函数应该是微不足道的,就像Michal已经为曲线本身提供的一样。
这里经过全面测试的代码复制并粘贴:
它借鉴approxidistant点沿曲线,和它绘制的切线。
bezierInterpolation
找到点
bezierTangent
找到切线
有两个版本的下方供给的bezierInterpolation
:
bezierInterpolation
作品完美
altBezierInterpolation
是完全一样的,但它是以扩大的,非常清楚的,解释性的方式写成的。它使得算术更容易理解。
使用这两个例程之一:结果是相同的。
在这两种情况下,请使用bezierTangent
来查找切线。 (注意:Michal的神话般的代码库here。)
一个完整的例子,如何使用drawRect:
也包括在内。
// MBBezierView.m original BY MICHAL stackoverflow #4058979
#import "MBBezierView.h"
CGFloat bezierInterpolation(
CGFloat t, CGFloat a, CGFloat b, CGFloat c, CGFloat d) {
// see also below for another way to do this, that follows the 'coefficients'
// idea, and is a little clearer
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;
}
CGFloat altBezierInterpolation(
CGFloat t, CGFloat a, CGFloat b, CGFloat c, CGFloat d)
{
// here's an alternative to Michal's bezierInterpolation above.
// the result is absolutely identical.
// of course, you could calculate the four 'coefficients' only once for
// both this and the slope calculation, if desired.
CGFloat C1 = (d - (3.0 * c) + (3.0 * b) - a);
CGFloat C2 = ((3.0 * c) - (6.0 * b) + (3.0 * a));
CGFloat C3 = ((3.0 * b) - (3.0 * a));
CGFloat C4 = (a);
// it's now easy to calculate the point, using those coefficients:
return (C1*t*t*t + C2*t*t + C3*t + C4 );
}
CGFloat bezierTangent(CGFloat t, CGFloat a, CGFloat b, CGFloat c, CGFloat d)
{
// note that abcd are aka x0 x1 x2 x3
/* the four coefficients ..
A = x3 - 3 * x2 + 3 * x1 - x0
B = 3 * x2 - 6 * x1 + 3 * x0
C = 3 * x1 - 3 * x0
D = x0
and then...
Vx = 3At2 + 2Bt + C */
// first calcuate what are usually know as the coeffients,
// they are trivial based on the four control points:
CGFloat C1 = (d - (3.0 * c) + (3.0 * b) - a);
CGFloat C2 = ((3.0 * c) - (6.0 * b) + (3.0 * a));
CGFloat C3 = ((3.0 * b) - (3.0 * a));
CGFloat C4 = (a); // (not needed for this calculation)
// finally it is easy to calculate the slope element,
// using those coefficients:
return ((3.0 * C1 * t* t) + (2.0 * C2 * t) + C3);
// note that this routine works for both the x and y side;
// simply run this routine twice, once for x once for y
// note that there are sometimes said to be 8 (not 4) coefficients,
// these are simply the four for x and four for y,
// calculated as above in each case.
}
@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];
// now mark in points along the bezier!
for (CGFloat t = 0.0; t <= 1.00001; t += 0.05) {
[[UIColor brownColor] setStroke];
CGPoint point = CGPointMake(
bezierInterpolation(t, p1.x, p2.x, p3.x, p4.x),
bezierInterpolation(t, p1.y, p2.y, p3.y, p4.y));
// there, use either bezierInterpolation or altBezierInterpolation,
// identical results for the position
// just draw that point to indicate it...
UIBezierPath *pointPath =
[UIBezierPath bezierPathWithArcCenter:point
radius:5 startAngle:0 endAngle:2*M_PI clockwise:YES];
[pointPath stroke];
// now find the tangent if someone on stackoverflow knows how
CGPoint vel = CGPointMake(
bezierTangent(t, p1.x, p2.x, p3.x, p4.x),
bezierTangent(t, p1.y, p2.y, p3.y, p4.y));
// the following code simply draws an indication of the tangent
CGPoint demo = CGPointMake(point.x + (vel.x*0.3),
point.y + (vel.y*0.33));
// (the only reason for the .3 is to make the pointers shorter)
[[UIColor whiteColor] setStroke];
UIBezierPath *vp = [UIBezierPath bezierPath];
[vp moveToPoint:point];
[vp addLineToPoint:demo];
[vp stroke];
}
}
@end
to draw that class...
MBBezierView *mm = [[MBBezierView alloc]
initWithFrame:CGRectMake(400,20, 600,700)];
[mm setNeedsDisplay];
[self addSubview:mm];
这里有两个例程以计算大约等距点,和那些的切线,沿一条Bezier三次。
为了清晰和可靠,这些例程以最简单,最具说明性的方式编写。
CGFloat bezierPoint(CGFloat t, CGFloat a, CGFloat b, CGFloat c, CGFloat d)
{
CGFloat C1 = (d - (3.0 * c) + (3.0 * b) - a);
CGFloat C2 = ((3.0 * c) - (6.0 * b) + (3.0 * a));
CGFloat C3 = ((3.0 * b) - (3.0 * a));
CGFloat C4 = (a);
return (C1*t*t*t + C2*t*t + C3*t + C4 );
}
CGFloat bezierTangent(CGFloat t, CGFloat a, CGFloat b, CGFloat c, CGFloat d)
{
CGFloat C1 = (d - (3.0 * c) + (3.0 * b) - a);
CGFloat C2 = ((3.0 * c) - (6.0 * b) + (3.0 * a));
CGFloat C3 = ((3.0 * b) - (3.0 * a));
CGFloat C4 = (a);
return ((3.0 * C1 * t* t) + (2.0 * C2 * t) + C3);
}
四个预先计算的值,C1 C2 C3 C4,有时称为系数贝塞尔的。(回想一下bc d通常被称为四个控制点。)
当然,t从0到1,例如每0.05。
只需一次单独调用这些例程一次X,然后Y.
希望它可以帮助别人!
重要的事实:
(1)这是一个绝对的事实是:不幸的是,有,当然,没有一种方法,由苹果公司提供,从UIBezierPath提取点。 (2)不要忘记,像沿着沿着UIBezierPath路径创建的动画一样简单。 Google many examples。
(3)很多人问,“Can not CGPathApply用于从UIBezierPath中提取点?”没有,CGPathApply是风马牛不相及的:它只是让你在做任何路径的指令列表(因此,“从这里开始”,“画一条直线到这个地步”,等等等等)
- 1. 添加三次Bezier曲线单张
- 2. 实现Bezier曲线
- 3. 三次Bezier实施
- 4. 在javascript中查找三次贝塞尔曲线的所有点
- 5. 将二次曲线转换为三次曲线
- 6. 如何选择Bezier样条曲线?
- 7. 从SVG文件中取出Bezier曲线
- 8. 关于Bezier曲线实现的问题?
- 9. Bezier曲线总是相同的长度
- 10. Bezier曲线上的等距点
- 11. 在bicubic bezier曲线上滚动
- 12. greensock tween找到bezier曲线的末端旋转
- 13. 三次/曲线平滑插补
- 14. 绘制椭圆与二次贝塞尔曲线和三次贝塞尔曲线
- 15. Snap.svg API帮助查找直线和二次曲线的交点
- 16. 如何计算三次Bezier曲线上P0 = P1时t = 0时的非零dx/dt和dy/dt?
- 17. 的Python:查找曲线
- 18. 查找曲线公式
- 19. 三角 - 查找其中两个曲线相交
- 20. 动画bezier直线
- 21. 将高阶贝塞尔曲线分解为许多三次曲线
- 22. 在特定路径(ex bezier曲线)上拖放as3
- 23. 在Bezier曲线中放置“好”控制点
- 24. 如何在UWP中沿着Cubic Bezier曲线制作UserControl动画
- 25. 为什么Bezier曲线变成iOS UIView中的形状?
- 26. Bezier曲线绘制拉伸椭圆在HTML5画布
- 27. bezier曲线在蓝牙绘图应用程序xcode 6
- 28. 如何在cocos2d中获取Bezier曲线上某点的坐标?
- 29. 在paper.js中沿着bezier曲线绘制文本
- 30. 沿着Bezier曲线路径的iPhone移动UI图像视图
非常优雅的输入广告我,谢谢。 (纯粹作为一种好奇心,在目前的Swift-iOS中,它们有一个f * -up,其中的代码行太长......不起作用,因此,可以将其分解为几个部分!) – Fattie 2018-01-15 01:26:59