Ответ 1
Лучший способ сгладить рисунок - использовать bezeir-кривую. Вот мой код. Это измененная версия, которую я нашел на веб-сайте apple dev, но я не помню исходную ссылку:
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;
}
Это будет опираться на три точки. Элемент управления - это средняя точка, которую нужно вернуть. Новая средняя точка будет отличаться от предыдущей. Кроме того, если вы пройдете через указанный выше код, он будет рисовать только половину строки. Следующий штрих заполнит его. Это необходимо. мой код для вызова этой функции (выше в C, это в 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];
Этот код получит среднюю точку на основе перевернутых точек iPad и установите "control" в качестве текущей точки.
Это сгладит края. Теперь, касаясь ширины линии, вам просто нужно найти скорость этого чертежа. Проще всего просто найти длину вашей линии. Это легко сделать, используя компонентную математику. У меня нет кода для него, но здесь является праймером для компонентной математики с сайта физики. Или вы можете просто делить (выше) количество на какой-то номер, чтобы узнать, насколько толстой вам нужна строка (count использует математику компонентов).
Я сохраняю данные точки в массиве с именем currentStroke, если это не очевидно.
Это должно быть все, что вам нужно.
EDIT:
Чтобы сохранить точки, вы должны использовать touchhesBegin и touchEnd:
- (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];
}
Это почти все приложение для рисования. Если вы используете GL_Paint, то вы уже используете точечные спрайты, на которых эта система построена.