2013-08-22 30 views
16

Tôi đang cố gắng tìm cách vẽ hình dạng biểu tượng 7 vòng tròn 'hình tròn' của iOS theo cách lập trình, sử dụng đồ họa lõi. Tôi không hỏi cách vẽ hình chữ nhật tròn. Một squircle là một superelipse:Vẽ hình chữ nhật theo phong cách iOS 7 theo chương trình

Squircle

đó là hơi khác so với một hình chữ nhật tròn thường xuyên: Rounded rectangle vs squircle

Music icon in squircle

Đó là công thức chính xác is readily available. Tuy nhiên, tôi không thể tìm ra cách để rút ra điều này bằng cách sử dụng, ví dụ, một CGPath, hãy để một mình điền vào nó, và có thể thay đổi kích thước nó khá dễ dàng. Tất cả điều này trong khi hoàn toàn chính xác với công thức. Bất kỳ ý tưởng?

+0

Tôi không biết cách tạo hình chữ nhật tròn; Tôi thực sự là siêu sao của loại hình tròn, khi chúng sử dụng cho biểu tượng springboard trên iOS 7. –

+2

@RemyVanherweghem Phương pháp 'bezierPathWithRoundedRect' đã được sửa đổi trong iOS 7 để vẽ các góc mượt mà hơn. Ngoài ra nó không có vẻ là một hình vuông: http://blog.mikeswanson.com/post/62341902567/unleashing-genetic-algorithms-on-the-ios-7-icon – millimoose

+0

(Điều đó nói rằng, phương thức 'UIBezierPath' không tạo ra một kết hợp hoàn hảo với mẫu biểu tượng, chúng chỉ gần hơn so với trước đây.) – millimoose

Trả lời

12

Trích từ Wikipedia: Superellipse

Đối với n = 1/2, đặc biệt, mỗi trong số bốn vòng cung là một đường cong bậc hai Bézier xác định bởi hai trục; kết quả là, mỗi cung là một phân đoạn của một parabol.

Vậy tại sao không cố gắng gần đúng Squircle bằng đường cong Bezier? Cả hai đường cong (Bezier và Squircle) đều được xác định bởi các phương trình tham số.

UIBezierPath Class có phương pháp: addCurveToPoint:controlPoint1:controlPoint2:

Gắn một đường cong Bézier khối để đường đi của người nhận.

LƯU Ý: Sử dụng phương pháp addQuadCurveToPoint:controlPoint: cho kết quả kém hơn - được kiểm tra.

tôi đã sử dụng phương pháp này và đó là những gì đã xảy ra kết quả là:

red line - hình chữ nhật tròn, blue line - Hình chữ nhật từ fours Bezier đường cong

Rounded rectangle vs cubic Bezier curve

Nếu kết quả này là quan tâm - vẽ mã bên dưới .

LƯU Ý: Để đạt được đường cong Bezier khớp chính xác hơn có thể được yêu cầu để thay đổi tọa độ của bốn corner points (bây giờ chúng tương ứng với các góc của hình chữ nhật trong đó được ghi hình).

CGContextRef context = UIGraphicsGetCurrentContext(); 
CGContextSaveGState(context); 

//set rect size for draw 
float rectSize = 275.; 
CGRect rectangle = CGRectMake(CGRectGetMidX(rect) - rectSize/2, CGRectGetMidY(rect) - rectSize/2, rectSize, rectSize); 

//Rounded rectangle 
CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor); 
UIBezierPath* roundedPath = [UIBezierPath bezierPathWithRoundedRect:rectangle cornerRadius:rectSize/4.7]; 
[roundedPath stroke]; 

//Rectangle from Fours Bezier Curves 
CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor); 
UIBezierPath *bezierCurvePath = [UIBezierPath bezierPath]; 

//set coner points 
CGPoint topLPoint = CGPointMake(CGRectGetMinX(rectangle), CGRectGetMinY(rectangle)); 
CGPoint topRPoint = CGPointMake(CGRectGetMaxX(rectangle), CGRectGetMinY(rectangle)); 
CGPoint botLPoint = CGPointMake(CGRectGetMinX(rectangle), CGRectGetMaxY(rectangle)); 
CGPoint botRPoint = CGPointMake(CGRectGetMaxX(rectangle), CGRectGetMaxY(rectangle)); 

//set start-end points 
CGPoint midRPoint = CGPointMake(CGRectGetMaxX(rectangle), CGRectGetMidY(rectangle)); 
CGPoint botMPoint = CGPointMake(CGRectGetMidX(rectangle), CGRectGetMaxY(rectangle)); 
CGPoint topMPoint = CGPointMake(CGRectGetMidX(rectangle), CGRectGetMinY(rectangle)); 
CGPoint midLPoint = CGPointMake(CGRectGetMinX(rectangle), CGRectGetMidY(rectangle)); 

//Four Bezier Curve 
[bezierCurvePath moveToPoint:midLPoint]; 
[bezierCurvePath addCurveToPoint:topMPoint controlPoint1:topLPoint controlPoint2:topLPoint]; 
[bezierCurvePath moveToPoint:midLPoint]; 
[bezierCurvePath addCurveToPoint:botMPoint controlPoint1:botLPoint controlPoint2:botLPoint]; 
[bezierCurvePath moveToPoint:midRPoint]; 
[bezierCurvePath addCurveToPoint:topMPoint controlPoint1:topRPoint controlPoint2:topRPoint]; 
[bezierCurvePath moveToPoint:midRPoint]; 
[bezierCurvePath addCurveToPoint:botMPoint controlPoint1:botRPoint controlPoint2:botRPoint]; 

[bezierCurvePath stroke]; 

CGContextRestoreGState(context); 
+0

Câu trả lời hay. Cảm ơn! –

2

Đây không phải là một câu trả lời tuyệt vời vì nó không có được trái tim của những gì bạn đang hỏi là làm thế nào để vẽ một superellipse ** lập trình, nhưng bạn có thể:

  1. Tải SVG cho iOS7 biểu tượng hình ở đây: http://dribbble.com/shots/1127699-iOS-7-icon-shape-PSD
  2. nhập nó vào dự án Xcode của bạn
  3. Thêm PocketSVG để dự án của bạn: https://github.com/arielelkin/PocketSVG
  4. Nạp SVG, và chuyển nó sang một UIBezierPath, từ đó bạn có thể mở rộng và biến đổi tuy nhiên bạn thích:

    PocketSVG *myVectorDrawing = [[PocketSVG alloc] initFromSVGFileNamed:@"iOS_7_icon_shape"]; 
    
    UIBezierPath *myBezierPath = myVectorDrawing.bezier; 
    
    // Apply your transforms here: 
    [myBezierPath applyTransform:CGAffineTransformMakeScale(2.5, 2.5)]; 
    [myBezierPath applyTransform:CGAffineTransformMakeTranslation(10, 50)]; 
    
    CAShapeLayer *myShapeLayer = [CAShapeLayer layer]; 
    myShapeLayer.path = myBezierPath.CGPath; 
    myShapeLayer.strokeColor = [[UIColor redColor] CGColor]; 
    myShapeLayer.lineWidth = 2; 
    myShapeLayer.fillColor = [[UIColor clearColor] CGColor]; 
    
    [self.view.layer addSublayer:myShapeLayer]; 
    

** Nó có lẽ đáng chú ý là hình dạng có thể không phải là một superellipse chính xác anyway: http://i.imgur.com/l0ljVRo.png

0

Đây sẽ là khá dễ dàng để làm trong OpenGL ES với một Shader. Chỉ cần vẽ một quad và vượt qua trong x và y là thuộc tính đỉnh. Trong shader fragment, cắm x và y vào phương trình. Nếu kết quả < = 1, thì đoạn nằm bên trong hình dạng. Nếu tôi có thể nhận được một số thời gian rảnh, tôi có thể thử điều này và đăng nó ở đây.

Nếu bạn muốn sử dụng CGPath, tôi nghĩ khóa là để tham số hóa x và y theo t, mà đi từ 0 đến 2π. Sau đó, đánh giá x và y theo chu kỳ đều đặn. Tôi sẽ cố gắng tìm ra điều này trong thời gian rảnh rỗi của tôi, nhưng toán học của tôi là loại gỉ.

BTW, tôi chắc chắn rằng Apple là không phải sử dụng công thức này. Xem các liên kết mà @millimoose gửi: http://blog.mikeswanson.com/post/62341902567/unleashing-genetic-algorithms-on-the-ios-7-icon

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