【问题标题】:How to draw a freehand-looking ellipse or circle?如何徒手画椭圆或圆形?
【发布时间】:2011-08-04 00:17:29
【问题描述】:

我的问题涉及绘制看似徒手画线的各种技术:

How do you draw like a Crayon?

特别是 Steve Hanov 发布了这个出色的 blog entry

由此我能够使用贝塞尔曲线为手绘线实现一个漂亮的算法。但是,我被困在如何实现手绘椭圆。理想情况下,我想给它一个矩形作为边界,类似于其他椭圆绘图调用。但是,我希望它看起来非常写意。

到目前为止,这是我想出的最好的:

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

结果如下:

我不喜欢它在顶部的尖锐程度,尽管我做了很多尝试,但还是无法让它变得更好。另外,我喜欢曲线看起来不那么完美,而不是将悬垂作为唯一的“徒手”外观部分。我认为 2 条四边形曲线只是错误的方式......

也许是 4 条弧线?

谁有其他解决方案或一些示例代码给我? (任何语言都可以)

【问题讨论】:

    标签: graphics drawing shapes ellipse


    【解决方案1】:

    所以这个问题已经开放了很长时间,让我试着试一试。有两个部分:(1)使路径看起来不完美。 (2) 像手绘一样抚摸路径。 对于 (1),将事物细分出来。将其从 100 个左右的控制点中提取出来,并使用缓慢变化的环绕函数扭曲它们。对于 (2),在路径上分配一个缓慢变化的连续厚度和角度,可能还会添加一些噪声。对于在 Perlin 噪声上读取的具有良好人类外观的噪声,这太棒了。此外,看看其他人是如何做的,在 Photoshop 中创建路径并对其进行描边总是一个好主意,它可以选择自然地进行。

    【讨论】:

      【解决方案2】:

      我个人会参数化定义你的椭圆,如下所示:

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

      然后制作一个生成小随机数的函数

      创建一个函数来找到曲线的法线向量(参数化)

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

      对于椭圆上的每个点,通过将该点的法线缩放一个小的随机数来偏移。

      使用三次插值绘制通过点的曲线。

      【讨论】:

        猜你喜欢
        • 2011-09-25
        • 1970-01-01
        • 1970-01-01
        • 2020-07-05
        • 2021-11-19
        • 2016-02-05
        • 1970-01-01
        • 1970-01-01
        • 2019-12-06
        相关资源
        最近更新 更多