【发布时间】: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