C'è un po ' semplice matematica dietro il calcolo delle posizioni, puoi leggere su di esso in ogni articolo che discute le curve di Bézier, anche su wikipedia. Ad ogni modo, posso relazionarmi con tutti quelli che hanno problemi a implementarlo realmente in codice, quindi ho scritto questo esempio di UIView perché è probabilmente il modo più semplice per iniziare.
#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
Questo è quello ottengo:
la matematica è divertente! +1! – slf
@Joe Blow: è davvero quello che volevi? Hai detto che volevi un punto che fosse una distanza D lungo la curva. Michal, correggimi se sbaglio, ma il tuo codice valuta solo la curva a valori di parametri diversi, che non è uguale alla lunghezza. Come puoi vedere, i punti sono più vicini tra loro nei picchi e più distanti nel mezzo della curva. – CromTheDestroyer
Ciao Crom - hai ragione, sono solo APPROSSIMATAMENTE equidistanti lungo la curva.Apparentemente non esiste un modo matematico per ottenere spaziature ESATTE. Questa comune approssimazione funziona bene per i motori di gioco e simili. Vedi anche 4089443. – Fattie