Comment lisser un ensemble de points dans une application de dessin iOS TOUT EN SE DÉPLACANT ? J'ai essayé UIBezierpaths mais tout ce que j'obtiens, ce sont des extrémités en dents de scie aux points d'intersection, lorsque je déplace simplement les points 1,2,3,4 - 2,3,4,5. J'ai entendu parler des courbes splines et de tous les autres types. Je suis assez novice en matière de programmation iPhone et je ne comprends pas comment programmer cela dans mon application de dessin quartz. Un exemple solide serait grandement apprécié, j'ai passé des semaines à tourner en rond et je ne semble jamais trouver de code iOS pour cette tâche. La plupart des articles renvoient à une simulation en Java ou à des pages de Wikipedia sur l'ajustement des courbes, ce qui ne m'apporte rien. De plus, je ne veux pas passer à l'openGL ES. J'espère que quelqu'un pourra enfin fournir du code pour répondre à cette question qui circule.
C'était mon code pour le UIBezierPath qui laissait les bords à l'intersection///.
MISE À JOUR D'UNE RÉPONSE CI-DESSOUS
#define VALUE(_INDEX_) [NSValue valueWithCGPoint:points[_INDEX_]]
#define POINT(_INDEX_) [(NSValue *)[points objectAtIndex:_INDEX_] CGPointValue]
- (UIBezierPath*)smoothedPathWithGranularity:(NSInteger)granularity
{
NSMutableArray *points = [(NSMutableArray*)[self pointsOrdered] mutableCopy];
if (points.count < 4) return [self bezierPath];
// Add control points to make the math make sense
[points insertObject:[points objectAtIndex:0] atIndex:0];
[points addObject:[points lastObject]];
UIBezierPath *smoothedPath = [self bezierPath];
[smoothedPath removeAllPoints];
[smoothedPath moveToPoint:POINT(0)];
for (NSUInteger index = 1; index < points.count - 2; index++)
{
CGPoint p0 = POINT(index - 1);
CGPoint p1 = POINT(index);
CGPoint p2 = POINT(index + 1);
CGPoint p3 = POINT(index + 2);
// now add n points starting at p1 + dx/dy up until p2 using Catmull-Rom splines
for (int i = 1; i < granularity; i++)
{
float t = (float) i * (1.0f / (float) granularity);
float tt = t * t;
float ttt = tt * t;
CGPoint pi; // intermediate point
pi.x = 0.5 * (2*p1.x+(p2.x-p0.x)*t + (2*p0.x-5*p1.x+4*p2.x-p3.x)*tt + (3*p1.x-p0.x-3*p2.x+p3.x)*ttt);
pi.y = 0.5 * (2*p1.y+(p2.y-p0.y)*t + (2*p0.y-5*p1.y+4*p2.y-p3.y)*tt + (3*p1.y-p0.y-3*p2.y+p3.y)*ttt);
[smoothedPath addLineToPoint:pi];
}
// Now add p2
[smoothedPath addLineToPoint:p2];
}
// finish by adding the last point
[smoothedPath addLineToPoint:POINT(points.count - 1)];
return smoothedPath;
}
- (PVPoint *)pointAppendingCGPoint:(CGPoint)CGPoint
{
PVPoint *newPoint = [[PVPoint alloc] initInsertingIntoManagedObjectContext:[self managedObjectContext]];
[newPoint setCGPoint:CGPoint];
[newPoint setOrder:[NSNumber numberWithUnsignedInteger:[[self points] count]]];
[[self mutableSetValueForKey:@"points"] addObject:newPoint];
[(NSMutableArray *)[self pointsOrdered] addObject:newPoint];
[[self bezierPath] addLineToPoint:CGPoint];
return [newPoint autorelease];
if ([self bezierPath] && [pointsOrdered count] > 3)
{
PVPoint *control1 = [pointsOrdered objectAtIndex:[pointsOrdered count] - 2];
PVPoint *control2 = [pointsOrdered objectAtIndex:[pointsOrdered count] - 1];
[bezierPath moveToPoint:[[pointsOrdered objectAtIndex:[pointsOrdered count] - 3] CGPoint]];
[[self bezierPath] addCurveToPoint:CGPoint controlPoint1:[control1 CGPoint] controlPoint2:[control2 CGPoint]];
}
}
- (BOOL)isComplete { return [[self points] count] > 1; }
- (UIBezierPath *)bezierPath
{
if (!bezierPath)
{
bezierPath = [UIBezierPath bezierPath];
for (NSUInteger p = 0; p < [[self points] count]; p++)
{
if (!p) [bezierPath moveToPoint:[(PVPoint *)[[self pointsOrdered] objectAtIndex:p] CGPoint]];
else [bezierPath addLineToPoint:[(PVPoint *)[[self pointsOrdered] objectAtIndex:p] CGPoint]];
}
[bezierPath retain];
}
return bezierPath;
}
- (CGPathRef)CGPath
{
return [[self bezierPath] CGPath];
}
0 votes
Pouvez-vous nous montrer les extrémités déchiquetées ?
0 votes
Veuillez regarder ci-dessus pour le code UIBezierPath.
0 votes
Il existe un exemple de code d'Apple appelé QuartzDemo.
0 votes
Je le sais mais cela ne permet pas d'obtenir des courbes lisses lorsque l'on dessine rapidement... J'ai besoin d'une formule de lissage ou quelque chose comme ça
0 votes
Pourriez-vous poster une capture d'écran de ce à quoi il ressemble actuellement ?
0 votes
Veuillez regarder ci-dessus pour l'image
0 votes
Si vous souhaitez comprendre en profondeur le sujet plutôt que de vous contenter d'exemples de code (ce qui, à long terme, sera une meilleure option), je vous recommande vivement de vous procurer une copie de l'ouvrage suivant Éléments mathématiques pour l'infographie (Rogers et Adams). Il a un peu vieilli car il a été écrit à l'époque des imprimantes matricielles, mais le traitement des courbes paramétriques, des splines, des béziers, etc. est absolument excellent et s'accompagne d'un pseudo-code solide.
0 votes
L'un des collègues avec qui je travaille a récemment publié un article sur les courbes de Bézier : scottlogic.co.uk/2011/08/bezier-demo Cela pourrait vous permettre de mieux comprendre le fonctionnement des béziers, j'espère que cela vous aidera.
0 votes
El Blog sur le dessin de lignes lisses Tony Ngo a expliqué en détail comment il l'a mis en œuvre. J'ai suivi sa technique et l'ai mise en œuvre sur une application iPad d'entreprise et cela fonctionne très bien.
0 votes
Avez-vous besoin d'une attribution ? ??
0 votes
Je ne suis pas sûr que vous en ayez besoin. Dans son blog, il mentionne que le code de son tutoriel est basé sur un projet de codeproject.com. Le code dans codeproject.com est sous The Code Project Open License (CPOL) 1.02.