Der beste Weg, um die Zeichnung zu glätten, ist eine Bezeir-Kurve. Hier ist mein Code. Es ist eine modifizierte Version, die ich auf dem Apple-Entwickler-Website gefunden, aber ich erinnere mich nicht den Original-Link:
CGPoint drawBezier(CGPoint origin, CGPoint control, CGPoint destination, int segments)
{
CGPoint vertices[segments/2];
CGPoint midPoint;
glDisable(GL_TEXTURE_2D);
float x, y;
float t = 0.0;
for(int i = 0; i < (segments/2); i++)
{
x = pow(1 - t, 2) * origin.x + 2.0 * (1 - t) * t * control.x + t * t * destination.x;
y = pow(1 - t, 2) * origin.y + 2.0 * (1 - t) * t * control.y + t * t * destination.y;
vertices[i] = CGPointMake(x, y);
t += 1.0/(segments);
}
//windowHeight is the height of you drawing canvas.
midPoint = CGPointMake(x, windowHeight - y);
glVertexPointer(2, GL_FLOAT, 0, vertices);
glDrawArrays(GL_POINTS, 0, segments/2);
return midPoint;
}
Das auf drei Punkten basierend wird remis. Das Steuerelement ist der Mittelpunkt, den Sie zurückgeben müssen. Der neue Mittelpunkt wird sich von dem vorherigen unterscheiden. Wenn Sie den obigen Code durchlaufen, wird nur die halbe Zeile angezeigt. Der nächste Strich füllt ihn aus. Dies ist erforderlich. mein Code, um diese Funktion für den Aufruf (die oben in C ist, dann ist dies in Obj-C):
//Invert the Y axis to conform the iPhone top-down approach
invertedYBegCoord = self.bounds.size.height - [[currentStroke objectAtIndex:i] CGPointValue].y;
invertedYEndCoord = self.bounds.size.height - [[currentStroke objectAtIndex:i+1] CGPointValue].y;
invertedYThirdCoord = self.bounds.size.height - [[currentStroke objectAtIndex:i+2] CGPointValue].y;
//Figure our how many dots you need
count = MAX(ceilf(sqrtf(([[currentStroke objectAtIndex:i+2] CGPointValue].x - [[currentStroke objectAtIndex:i] CGPointValue].x)
* ([[currentStroke objectAtIndex:i+2] CGPointValue].x - [[currentStroke objectAtIndex:i] CGPointValue].x)
+ ((invertedYThirdCoord - invertedYBegCoord) * (invertedYThirdCoord - invertedYBegCoord)))/pointCount), 1);
newMidPoint = drawBezier(CGPointMake([[currentStroke objectAtIndex:i] CGPointValue].x, invertedYBegCoord), CGPointMake([[currentStroke objectAtIndex:i+1] CGPointValue].x, invertedYEndCoord), CGPointMake([[currentStroke objectAtIndex:i+2] CGPointValue].x, invertedYThirdCoord), count);
int loc = [currentStroke count]-1;
[currentStroke insertObject:[NSValue valueWithCGPoint:newMidPoint] atIndex:loc];
[currentStroke removeObjectAtIndex:loc-1];
Dieser Code wird den Mittelpunkt basierend auf invertierten iPad Punkte, und stellen Sie die ‚Kontrolle‘ als die aktuelle erhalten Punkt.
Das wird die Kanten glätten. In Bezug auf die Linienbreite musst du nur noch die Geschwindigkeit dieser Zeichnung finden. Es ist am einfachsten, nur die Länge Ihrer Linie zu finden. Dies kann leicht unter Verwendung von Komponentenmathematik durchgeführt werden. Ich habe keinen Code dafür, aber ist eine Grundierung für Komponente Mathematics von einer Physik-Website. Oder Sie können (oben) einfach durch eine Zahl teilen, um herauszufinden, wie dick die Linie sein muss (Zählung verwendet Komponenten Mathematik).
Ich speicherpunkt Daten in einem Array namens currentStroke, falls es nicht offensichtlich war.
Das sollte alles sein, was Sie brauchen.
EDIT:
Punkte zu speichern, sollten Sie touchesBegin und touchesEnd:
- (void) touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
{
self.currentStroke = [NSMutableArray array];
CGPoint point = [ [touches anyObject] locationInView:self];
[currentStroke addObject:[NSValue valueWithCGPoint:point]];
[self draw];
}
- (void) touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event
{
CGPoint point = [ [touches anyObject] locationInView:self];
[currentStroke addObject:[NSValue valueWithCGPoint:point]];
[self draw];
}
- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
CGPoint point = [ [touches anyObject] locationInView:self];
[currentStroke addObject:[NSValue valueWithCGPoint:point]];
[self draw];
}
, dass die Anwendung so ziemlich eine ganze Zeichnung ist da. Wenn Sie GL_Paint verwenden, verwenden Sie bereits Punkt-Sprites, auf denen dieses System basiert.
Vielen Dank, das hilft wirklich. Aber ich bin mir nicht sicher, wo ich den zweiten Teil des Codes implementieren soll. Im GLPaint-Beispiel gibt es eine Funktion renderLineFromPoint: toPoint :, die jedes Mal aufgerufen wird, wenn der Benutzer seinen Finger bewegt. Muss ich den zweiten Teil Ihres Codes in diese Funktion einfügen? – burki
Oder könnten Sie den ganzen Code hinzufügen? Ich meine die vollständigen Methoden. Das wäre sehr nett. – burki
Zusätzliche BerührungenBeginn, berührtMoved und berührtEnd. Das ist so ziemlich eine komplette openGL-Zeichnungsanwendung in der Post. – Beaker