gpt4 book ai didi

objective-c - 获取沿 NSBezier 路径的任意点

转载 作者:行者123 更新时间:2023-12-03 16:55:15 26 4
gpt4 key购买 nike

对于我正在编写的程序,我需要能够追踪对象必须沿着的虚拟线(不是直的)。我正在考虑使用 NSBezierPath 来绘制这条线,但我找不到一种方法来获取沿线的任何点,我必须这样做,这样我才能沿着它移动对象。

任何人都可以建议一种沿着 NSBezierPath 找到点的方法吗?如果那不可能,任何人都可以建议一种方法来执行上述操作吗?

最佳答案

编辑:下面的代码仍然准确,但有更快的方法来计算它。请参阅Introduction to Fast BezierEven Faster Bezier .

<小时/>

有两种方法可以解决这个问题。如果您只需要沿线移动某些内容,请使用CAKeyframeAnimation。这非常简单,您永远不需要计算分数。

另一方面,如果由于某种原因您确实需要知道该点,则必须自己计算贝塞尔曲线。例如,您可以从 iOS 5 Programming Pushing the Limits 获取第 18 章的示例代码。 。 (它是为 iOS 编写的,但同样适用于 Mac。)查看 CurvyTextView.m

给定控制点 P0_P3_,以及 0 和 1 之间的偏移量(见下文),pointForOffset: 将为您提供该点沿途:

static double Bezier(double t, double P0, double P1, double P2,
double P3) {
return
pow(1-t, 3) * P0
+ 3 * pow(1-t, 2) * t * P1
+ 3 * (1-t) * pow(t, 2) * P2
+ pow(t, 3) * P3;
}

- (CGPoint)pointForOffset:(double)t {
double x = Bezier(t, P0_.x, P1_.x, P2_.x, P3_.x);
double y = Bezier(t, P0_.y, P1_.y, P2_.y, P3_.y);
return CGPointMake(x, y);
}

注意:此代码违反了我的基本规则之一:始终使用访问器而不是直接访问 ivars。这是因为它被调用了数千次,并且消除方法调用会对性能产生显着的影响。

“偏移”并不是一件容易解决的事情。它不会沿着曲线线性进行。如果您需要沿曲线均匀分布的点,则需要计算每个点的正确偏移量。这是通过以下例程完成的:

// Simplistic routine to find the offset along Bezier that is
// aDistance away from aPoint. anOffset is the offset used to
// generate aPoint, and saves us the trouble of recalculating it
// This routine just walks forward until it finds a point at least
// aDistance away. Good optimizations here would reduce the number
// of guesses, but this is tricky since if we go too far out, the
// curve might loop back on leading to incorrect results. Tuning
// kStep is good start.
- (double)offsetAtDistance:(double)aDistance
fromPoint:(CGPoint)aPoint
offset:(double)anOffset {
const double kStep = 0.001; // 0.0001 - 0.001 work well
double newDistance = 0;
double newOffset = anOffset + kStep;
while (newDistance <= aDistance && newOffset < 1.0) {
newOffset += kStep;
newDistance = Distance(aPoint,
[self pointForOffset:newOffset]);
}
return newOffset;
}

我将 Distance() 留给读者作为练习,但它当然在示例代码中。

如果您需要的话,引用的代码还提供了 BezierPrime()angleForOffset: 。 iOS:PTL 第 18 章在如何沿着任意路径绘制文本的讨论中更详细地介绍了这一点。

关于objective-c - 获取沿 NSBezier 路径的任意点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8818798/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com