2011-09-19 9 views
6

Actualmente estoy trabajando en un proyecto de iPad donde necesito la funcionalidad para permitir al usuario escribir en un papel con un lápiz.Escritura fluida en iPad

He probado un par de lápices y descubrí que el bambú era el mejor. También tienen una aplicación gratuita que puedes usar para escribir.

El problema al que me enfrento es que el método que uso no ofrece curvas suaves. La aplicación de papel de bambú proporciona líneas de aspecto perfecto. Este es el código que tengo hasta ahora:

- (void)drawRect:(CGRect)rect 
{ 
    CGContextRef context = UIGraphicsGetCurrentContext(); 
    UIGraphicsBeginImageContext(self.frame.size); 

    // draw accumulated lines 
    if ([self.lines count] > 0) { 
     for (Line *tempLine in self.lines){ 
      CGContextSetAlpha(context, tempLine.opacity); 
      CGContextSetStrokeColorWithColor(context, tempLine.lineColor.CGColor); 
      CGContextSetLineWidth(context, tempLine.lineWidth); 
      CGContextSetLineCap(context, kCGLineCapRound); 
      CGContextSetLineJoin(context, kCGLineJoinRound); 
      CGContextAddPath(context, tempLine.linePath); 
      CGContextStrokePath(context); 

      } 
    } 

    //draw current line 
    CGContextSetAlpha(context, self.currentLine.opacity); 


    CGContextSetStrokeColorWithColor(context, self.currentLine.lineColor.CGColor); 
    CGContextSetLineWidth(context, self.currentLine.lineWidth); 
    CGContextSetLineCap(context, kCGLineCapRound); 
    CGContextSetLineJoin(context, kCGLineJoinRound); 
    CGContextBeginPath(context); 
    CGContextAddPath(context, self.currentLine.linePath); 
    CGContextStrokePath(context); 


    UIGraphicsEndImageContext(); 


} 

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { 
    UITouch *touch = [touches anyObject]; 
    CGPoint cPoint = [touch locationInView:self]; 

    CGPathMoveToPoint(self.currentLine.linePath, NULL, cPoint.x, cPoint.y); 

    [self setNeedsDisplay]; 
} 

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { 
    UITouch *touch = [touches anyObject]; 
    CGPoint currentPoint = [touch locationInView:self]; 

    CGPathAddLineToPoint(self.currentLine.linePath, NULL, currentPoint.x, currentPoint.y); 

    [self setNeedsDisplay]; 
} 

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { 
    UITouch *touch = [touches anyObject]; 
    CGPoint cPoint = [touch locationInView:self]; 
    CGPathAddLineToPoint(self.currentLine.linePath, NULL, cPoint.x, cPoint.y); 

    [self setNeedsDisplay]; 
    [self.lines addObject:self.currentLine]; 
    Line *nextLine = [[Line alloc] initWithOptions:self.currentLine.lineWidth color:self.currentLine.lineColor opacity:self.currentLine.opacity]; 
    self.currentLine = nextLine; 
    [nextLine release]; 
} 

Aquí están las imágenes que dejan en claro qué problema estoy enfrentando. Esta es la imagen de lo que se genera cuando la escritura con el código proporcionado anteriormente:

enter image description here

Esta es la imagen si escribo lo mismo en la aplicación de papel Mamboo:

enter image description here

¿El ¿Alguien tiene una idea de cómo escribir bien en la aplicación mamboo?

+0

posible duplicado de [iPhone algoritmo de dibujo boceto liso] (http://stackoverflow.com/questions/5076622/iphone-smooth-sketch-drawing-algorithm) –

+0

Véase también [cómo puedo rastrear el movimiento de los dedos en el tacto para dibujar curvas suaves?] (http://stackoverflow.com/questions/1052119/how-can-i-trace-the-finger-movement-on-touch-for-drawing-smooth-curves). –

+0

ver muestra https: // github.com/yusenhan/Smooth-Line-View –

Respuesta

7

En lugar de unir los puntos usando líneas rectas (CGPathAddLineToPoint), debería intentar usar las curvas de bezier: CGPathAddCurveToPoint o CGPathAddQuadCurveToPoint.

Esto es lo que hará el suavizado.


Si no está familliar con curvas de Bezier, es probable que encuentre interesantes the wikipedia page about Bézier curves (no específicamente las ecuaciones matemáticas, pero mira el bocetos e imágenes animadas). Le dará la idea general de cómo los puntos de control afectan el alisado de las líneas alrededor de los puntos clave de su línea.

Para su caso, las curvas cuadráticas (solo un punto de control para cada subsegmento entre dos de sus puntos clave) deberían ser suficientes.

Construction of a quadratic Bézier curve - Source: Wikipedia (Una línea de P0 a P1, suavizado usando punto de control P1)


Un ejemplo (fuera de la caja, sólo una sugerencia de la cabeza, no probado, adaptar la coeficientes a sus necesidades) para calcular este punto de control C entre cada uno de sus puntos clave A y B es hacer que el AC sea, digamos, 2/3 de la longitud de AB, y (AB, AC) haciendo un ángulo de 30 grados o similar a sthg.

Incluso puede proponer en la configuración de su aplicación ajustar la fuerza de suavizado con un control deslizante, lo que afectará los valores que elija para calcular cada punto de control y ver qué coeficientes se ajusta mejor.

+0

Ok, nunca usé bezier curves en una aplicación iOS (los usé hace un par de años para un juego Java si lo recuerdo bien) Buscaré en internet algunos buenos ejemplos . Si tiene algunos buenos ejemplos, hágamelo saber: D ¡Gracias por su respuesta! (el objeto linePath que ahora uso es un CGMutablePathRef) – CyberK

+0

No estoy seguro de haberlo visto, pero edité mi respuesta desde la primera respuesta con algunas sugerencias;) – AliSoftware

+0

Sí, lo he visto ;-) – CyberK

Cuestiones relacionadas