Hoe teken ik een uit de vrije hand ogende ellips of cirkel?

Mijn vraag heeft betrekking op verschillende technieken voor het tekenen van lijnen die uit de vrije hand lijken te zijn:

Hoe teken je als een krijt?

In het bijzonder plaatste Steve Hanov dit uitstekende blogbericht

Daaruit kon ik een mooi uitziend algoritme implementeren voor lijnen uit de vrije hand met behulp van bezier-curven. Ik zit echter vast aan het implementeren van een uit de vrije hand ogende ellips. Idealiter zou ik het een rect willen geven om als grens te gebruiken, vergelijkbaar met andere ellips-tekenoproepen. Maar ik wil dat het er heel uit de vrije hand uitziet.

Het beste wat ik tot nu toe heb bedacht:

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

Het resultaat ziet er als volgt uit:

freehand ellipse

Het bevalt me ​​niet hoe puntig het bovenaan is, en ondanks al mijn pogingen kan ik het gewoon niet krijgen het is veel beter. Bovendien vind ik het prettig dat de rondingen er minder perfect uitzien en niet vertrouwen op de overhang als het enige "uit de vrije hand" ogende onderdeel. Ik denk dat 2 quadcurves gewoon de verkeerde weg zijn .....

Misschien 4 bogen?

Heeft iemand een andere oplossing of een voorbeeldcode voor mij? (elke taal is prima)

7
задан Community 23 May 2017 в 11:53
поделиться