2011-08-04 21 views
7

Moje pytanie dotyczy różnych technik rysunku linie, które wydają się być odręczne:Jak narysować elipsę lub okrąg odręczny?

How do you draw like a Crayon?

Konkretnie Steve Hanov pisał ten doskonały blog entry.

Dzięki temu mogłem zaimplementować ładnie wyglądający algorytm dla linii odręcznych za pomocą krzywych Beziera. Jednak utknąłem na tym, jak zaimplementować odręczną elipsę. Idealnie, chciałbym nadać temu prostemu użycie jako granicę, podobnie do innych wywołań rysowania elipsy. Ale chcę, żeby wyglądała bardzo odręcznie.

tej pory najlepszy jaki mają pochodzić z tego:

- (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; 
} 

Wynik wygląda tak:

freehand ellipse

nie lubię, jak wskazał to na górze, i pomimo wszystkich moich prób, po prostu nie mogę tego poprawić. Poza tym podoba mi się, że krzywe wyglądają mniej perfekcyjnie i nie polegają na tym, że zwis jest jedyną "odręczną" częścią. Myślę, że 2 zakręty czteropunktowe są po prostu niewłaściwą drogą .....

Może 4 łuki?

Ktoś ma inne rozwiązanie lub przykładowy kod dla mnie? (dowolny język jest w porządku)

Odpowiedz

0

Pytanie to było otwarte od dawna, pozwól mi spróbować. Są dwie części: (1) Sprawienie, by ścieżka nie była idealna. (2) Głaskanie ścieżki jak rysowane ręcznie. Dla (1), podziel gówno z rzeczy. Zrób co najmniej 100 punktów kontrolnych i zniekształć je za pomocą funkcji owijania, która zmienia się powoli. Dla (2) przypisz wolno zmieniającą się, ciągłą grubość i kąt na ścieżce, być może dodając trochę szumu. Dla dobrego ludzkiego szelestu odczytywanego w hałasie Perlin, jest niesamowity. Zawsze dobrze jest też spojrzeć na to, jak inni to robią, tworzyć ścieżki w Photoshopie i je gładzić, ma opcję zrobienia tego w naturalny sposób.

1

Osobiście chciałbym zdefiniować elipsę parametrycznie, tak:

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

następnie utworzyć funkcję, która generuje małych liczb losowych

zrobić funkcję, która znajdzie się wektor normalny do krzywej (parametrycznie)

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

dla każdego punktu na elipsie, przesuniętego przez skalowanie normalnego w tym punkcie o małą liczbę losową.

Narysuj krzywą w punktach za pomocą interpolacji sześciennej.

Powiązane problemy