2011-08-04 41 views
7

Mi pregunta implica diversas técnicas para dibujar líneas que parecen ser a mano alzada:¿Cómo dibujar una elipse o círculo a mano alzada?

How do you draw like a Crayon?

Específicamente Steve Hanov publicado esto blog entry excelente.

A partir de eso, pude implementar un bonito algoritmo para líneas a mano alzada usando curvas bezier. Sin embargo, estoy atascado en cómo implementar una elipse de aspecto a mano alzada. Idealmente, me gustaría darle un rect para usar como un límite, similar a otras llamadas de dibujo de elipse. Pero, quiero que luzca muy a mano alzada.

Hasta el momento, la mejor que han llegado con esto:

- (UIBezierPath*) freehandEllipseFromRect:(CGRect) rect { 

    // freehand ellipses need a lil more height 
    rect = CGRectMake(rect.origin.x, rect.origin.y-5, rect.size.width, rect.size.height+10); 

    UIBezierPath* path = [UIBezierPath bezierPath]; 


    CGPoint topMidPoint = CGPointMake(rect.origin.x + (rect.size.width/2), rect.origin.y); 
    CGPoint bottomMidPoint = CGPointMake(rect.origin.x + (rect.size.width/2), rect.origin.y+rect.size.height); 


    // random point along bottom quarter of height, cause makes it look better 
    CGFloat randomY = (((CGFloat) (arc4random() % RAND_MAX)/RAND_MAX)) * (rect.size.height/4); 
    CGPoint leftControlPoint = CGPointMake(rect.origin.x-(rect.size.width), rect.origin.y+(rect.size.height-randomY)); 


    // another random y; 
    randomY = (((CGFloat) (arc4random() % RAND_MAX)/RAND_MAX)) * (rect.size.height/4); 
    CGPoint rightControlPoint = CGPointMake(rect.origin.x+(rect.size.width*2), rect.origin.y+(rect.size.height-randomY)); 

    CGFloat overshootValueX = (((CGFloat) (arc4random() % RAND_MAX)/RAND_MAX)) * 4; 
    CGFloat overshootValueY = (((CGFloat) (arc4random() % RAND_MAX)/RAND_MAX)) * 6; 
    [path moveToPoint:CGPointMake(topMidPoint.x+overshootValueX, topMidPoint.y)];   
    [path addQuadCurveToPoint:bottomMidPoint controlPoint:leftControlPoint]; 

    // random value to overshoot 
    overshootValueX = (((CGFloat) (arc4random() % RAND_MAX)/RAND_MAX)) * 20; 
    overshootValueY = (((CGFloat) (arc4random() % RAND_MAX)/RAND_MAX)) * 4; 
    [path addQuadCurveToPoint:CGPointMake(topMidPoint.x-overshootValueX, topMidPoint.y-overshootValueY) controlPoint:rightControlPoint]; 
    return path; 
} 

El resultado es el siguiente:

freehand ellipse

no me gusta la forma señaló que es en la parte superior, y a pesar de todo lo que intento, simplemente no puedo hacerlo mucho mejor. Además, me gusta que las curvas se vean menos perfectas, y no confío en el voladizo como la única parte que se ve a "mano alzada". Creo que 2 curvas cuádruples son simplemente el camino equivocado ...

¿Tal vez 4 arcos?

¿Alguien tiene otra solución o código de muestra para mí? (cualquier idioma está bien)

Respuesta

0

Así que esta pregunta ha estado abierta durante mucho tiempo, permítanme intentar darle una oportunidad. Hay dos partes: (1) Hacer que el camino no se vea perfecto. (2) Acariciando el camino como dibujado a mano. Para (1), subdivida la mierda de la cosa. Haga de 100 o más puntos de control y distorsione con una función de envolver que varía lentamente. Para (2) asignar un grosor y un ángulo continuos que varían lentamente y sobre el camino, tal vez también agregue algo de ruido. Para un buen ruido de aspecto humano, lee el ruido de Perlin, es increíble. También siempre es una buena idea mirar cómo lo hacen otras personas, crear rutas en Photoshop y acariciarlas, tiene la opción de hacerlo de forma natural.

1

Personalmente me gustaría definir su elipse de forma paramétrica, de esta manera:

x=(width*cos(t)/2)+centerx; 
y=(height*cos(t)/2)+centery; 

girar a la función que genera pequeños números aleatorios

hacer una función que encuentra el vector normal a la curva (paramétrica)

x=width*cos(t); 
y=height*sin(t); 
normal=UnitVector(x,y); 

por cada punto en su elipse, compensado por la escala de la normal en ese punto con un pequeño número aleatorio.

Dibuja una curva a través de los puntos utilizando la interpolación cúbica.

Cuestiones relacionadas