Najlepszym sposobem na wygładzenie rysunku jest użycie krzywej Bezeir. Oto mój kod. Jest to zmodyfikowana wersja, którą znalazłem na stronie Apple'a, ale nie pamiętam oryginalnego linku:
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;
}
To będzie losować na podstawie trzech punktów. Kontrola to punkt środkowy, który musisz zwrócić. Nowy punkt środkowy będzie inny niż poprzedni. Ponadto, jeśli przejdziesz powyższy kod, pobierze on tylko połowę linii. Następny skok wypełni go. Jest to wymagane. mój kod do wywoływania tej funkcji (powyższe jest w C, to jest w 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];
Ten kod dostanie punktu środkowego na podstawie odwróconych punktów iPad i ustaw „kontrola” jak prąd punkt.
To wygładzi krawędzie. Jeśli chodzi o szerokość linii, wystarczy znaleźć prędkość tego rysunku. Najłatwiej jest znaleźć długość linii. Można to łatwo zrobić za pomocą matematyki komponentów. Nie mam dla niego kodu, ale here jest podkładem dla matematyki komponentowej z witryny fizyki. Lub możesz po prostu podzielić (powyżej) liczbę przez pewną liczbę, aby dowiedzieć się, jak gruby potrzebujesz linii (liczenie wykorzystuje matematykę elementów).
Przechowuję dane punktu w tablicy o nazwie currentStroke, na wypadek, gdyby nie było oczywiste.
To wszystko, czego potrzebujesz.
EDIT:
Aby zapisać punkty, należy użyć touchesBegin i 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];
}
To jest dość dużo cała aplikacja jest rysunek. Jeśli używasz GL_Paint, to już używasz duszków punktowych, na których ten system jest zbudowany.
Dziękuję bardzo, to naprawdę pomaga. Ale nie jestem pewien, gdzie zaimplementować drugą część kodu. W przykładzie GLPaint istnieje funkcja renderLineFromPoint: toPoint :, która jest wywoływana za każdym razem, gdy użytkownik przesuwa palec. Czy muszę włożyć drugą część kodu do tej funkcji? – burki
Czy możesz dodać cały kod? Mam na myśli pełne metody. To byłoby bardzo miłe. – burki
Dodano touchBegin, touchSove i touchEnd. Jest to prawie cała aplikacja do rysowania OpenGL w poście. – Beaker