我的问题涉及绘制似乎是徒手的线条的各种技巧:
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弧?
有人为我提供了其他解决方案或示例代码吗? (任何语言都可以)
答案 0 :(得分:1)
所以这个问题已经开放了很长时间,让我试着试一试。有两个部分:(1)使路径看起来不完美。 (2)抚摸手绘的路径。 对于(1),将狗屎细分出来。从100个左右的控制点中取出它,并使用缓慢变化的包装功能对它们进行扭曲。对于(2)在路径上分配缓慢变化的连续厚度和角度,可能还会增加一些噪声。为了获得有关Perlin噪音的良好人类视觉噪音,它非常棒。另外,看看其他人如何做到这一点,在Photoshop中创建路径并抚摸它们,它总是一个好主意,它可以自然地选择。
答案 1 :(得分:1)
就个人而言,我会以参数方式定义椭圆,如下所示:
x=(width*cos(t)/2)+centerx;
y=(height*cos(t)/2)+centery;
然后创建一个生成小随机数的函数
创建一个函数,找到曲线的法线向量(参数化)
x=width*cos(t);
y=height*sin(t);
normal=UnitVector(x,y);
对于椭圆上的每个点,通过用一个小的随机数在该点缩放法线来抵消。
使用三次插值在点上绘制曲线。