2011-08-04 57 views
7

Câu hỏi của tôi liên quan đến kỹ thuật khác nhau để vẽ đường có vẻ như là tự do:Làm cách nào để vẽ hình elip hoặc vòng tròn tự do?

How do you draw like a Crayon?

Cụ Steve Hanov posted tuyệt vời blog entry này.

Từ đó tôi đã có thể triển khai thuật toán tìm kiếm đẹp mắt cho các đường tự do sử dụng đường cong bezier. Tuy nhiên, tôi bị mắc kẹt về cách thực hiện một hình elip tìm kiếm tự do. Lý tưởng nhất, tôi muốn cung cấp cho nó một rect để sử dụng như một ranh giới, tương tự như các cuộc gọi vẽ hình elip khác. Nhưng, tôi muốn nó trông rất tự do.

Cho đến nay, các tốt nhất mà tôi đã đưa ra với điều này:

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

Kết quả trông như thế này:

freehand ellipse

tôi không thích như thế nào chỉ là trên đầu trang, và mặc dù tất cả cố gắng của tôi tôi chỉ không thể làm cho nó tốt hơn nhiều. Thêm vào đó, tôi thích các đường cong trông ít hoàn hảo hơn, và không dựa vào phần nhô ra như phần tìm kiếm "tự do" duy nhất. Tôi nghĩ rằng 2 đường cong quad chỉ là sai cách để đi .....

Có lẽ 4 vòng cung?

Bất kỳ ai có giải pháp khác hoặc một số mã mẫu cho tôi? (bất kỳ ngôn ngữ nào là tốt)

Trả lời

0

Vì vậy, câu hỏi này đã được mở trong một thời gian dài, hãy để tôi cố gắng cho nó một shot. Có hai phần: (1) Làm cho đường đi trông không hoàn hảo. (2) Vuốt con đường như vẽ bằng tay. Đối với (1), hãy chia nhỏ thông tin. Làm cho nó ra khỏi 100 hoặc để kiểm soát các điểm và bóp méo chúng với một chức năng gói mà thay đổi chậm. Đối với (2) chỉ định một độ dày và độ dày liên tục khác nhau trên con đường, cũng có thể thêm một số tiếng ồn. Đối với một tiếng ồn tốt của con người tìm kiếm đọc trên tiếng ồn Perlin, nó là tuyệt vời. Ngoài ra nó luôn luôn là một ý tưởng tốt để xem làm thế nào người khác làm điều đó, tạo ra con đường trong Photoshop và đột quỵ chúng, nó có một tùy chọn để làm điều đó tự nhiên tìm kiếm.

1

Cá nhân tôi sẽ xác định hình elip của bạn parametrically, như thế này:

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

sau đó tạo ra một chức năng mà tạo ra số ngẫu nhiên nhỏ

làm một chức năng tìm vector vuông góc với đường cong (parametrically)

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

cho mỗi điểm trên hình elip của bạn, được bù trừ bằng cách chia tỷ lệ bình thường tại điểm đó bằng một số ngẫu nhiên nhỏ.

Vẽ đường cong qua các điểm bằng cách sử dụng phép nội suy khối.

Các vấn đề liên quan