2012-05-01 18 views
5

Tôi đang tìm cách tạo lập trình sao, sunburst và các hiệu ứng "nhọn" khác bằng cách sử dụng UIBezierPath.iPhone iOS Tạo sao, sunburst hoặc đa giác UIBezierPath theo lập trình

Starburst image

UIBezierPath *sunbeamsPath = [UIBezierPath bezierPath]; 
[sunbeamsPath moveToPoint: CGPointMake(x, y)]; 

Có bất kỳ thuật toán mà có thể tạo ra điểm cho sunburst như hình dạng lập trình, mà không cần đường dẫn chồng chéo?

Tôi cũng quan tâm đến một hình dạng bất thường sunburst như hình dưới đây:

irregular sunburst

Tôi tưởng tượng rằng thuật toán như vậy sẽ mất một số lượng nhất định các tia, sau đó khoảng phân chia vòng tròn trong một số các phân đoạn và tạo điểm cho phân đoạn đó theo chiều kim đồng hồ. Có phải một thuật toán giống như thuật toán tôi đang mô tả đã tồn tại hay tôi sẽ tự viết một thuật toán?

Cảm ơn bạn!

Trả lời

6

Tôi biết điều này cũ, nhưng tôi đã tò mò về phần đầu tiên của câu hỏi này bản thân mình, và đi tắt bài jrturton, tôi tạo ra một UIView tùy chỉnh mà tạo ra một UIBezierPath từ trung tâm của xem. Ngay cả hoạt hình nó quay cho điểm thưởng. Dưới đây là kết quả:

enter image description here

Code tôi sử dụng ở đây:

- (void)drawRect:(CGRect)rect { 
CGFloat radius = rect.size.width/2.0f; 

[self.fillColor setFill]; 
[self.strokeColor setStroke]; 

UIBezierPath *bezierPath = [UIBezierPath bezierPath]; 
CGPoint centerPoint = CGPointMake(rect.origin.x + radius, rect.origin.y + radius); 

CGPoint thisPoint = CGPointMake(centerPoint.x + radius, centerPoint.y); 
[bezierPath moveToPoint:centerPoint]; 

CGFloat thisAngle = 0.0f; 
CGFloat sliceDegrees = 360.0f/self.beams/2.0f; 

for (int i = 0; i < self.beams; i++) { 

    CGFloat x = radius * cosf(DEGREES_TO_RADIANS(thisAngle + sliceDegrees)) + centerPoint.x; 
    CGFloat y = radius * sinf(DEGREES_TO_RADIANS(thisAngle + sliceDegrees)) + centerPoint.y; 
    thisPoint = CGPointMake(x, y); 
    [bezierPath addLineToPoint:thisPoint]; 
    thisAngle += sliceDegrees; 

    CGFloat x2 = radius * cosf(DEGREES_TO_RADIANS(thisAngle + sliceDegrees)) + centerPoint.x; 
    CGFloat y2 = radius * sinf(DEGREES_TO_RADIANS(thisAngle + sliceDegrees)) + centerPoint.y; 
    thisPoint = CGPointMake(x2, y2); 
    [bezierPath addLineToPoint:thisPoint]; 
    [bezierPath addLineToPoint:centerPoint]; 
    thisAngle += sliceDegrees; 

} 

[bezierPath closePath]; 

bezierPath.lineWidth = 1; 
[bezierPath fill]; 
[bezierPath stroke]; 

}

Và bạn có thể tải về một dự án mẫu ở đây:

https://github.com/meekapps/Sunburst

2

Tôi không biết thuật toán để tạo ra nhưng tôi có một số lời khuyên - tạo đường bezier của bạn sao cho (0,0) là trung tâm của sunburst, sau đó xác định nhiều điểm bạn cần vẽ "chùm" của sunburst của bạn đi lên trên, trở về (0,0)

Sau đó, đối với nhiều dầm tùy ý, hãy thực hiện vòng lặp: áp dụng phép biến đổi xoay (2 pi/số dầm) thành điểm tia nắng của bạn (CGPointApplyTransform) và thêm chúng vào đường dẫn.

Khi bạn hoàn tất, bạn có thể dịch và chia tỷ lệ đường dẫn để vẽ.

Tôi đã sử dụng quy trình tương tự để vẽ đa giác sao gần đây và nó rất đơn giản. Tín dụng cho Rob Napier's cuốn sách cho ý tưởng.

0

Phiên bản Swift cho số này

import UIKit 

extension Int { 
    var degreesToRadians: Double { return Double(self) * .pi/180 } 
    var radiansToDegrees: Double { return Double(self) * 180/.pi } 
} 
extension FloatingPoint { 
    var degreesToRadians: Self { return self * .pi/180 } 
    var radiansToDegrees: Self { return self * 180/.pi } 
} 

class SunBurstView: UIView { 

    override func draw(_ rect: CGRect) { 
     let radius: CGFloat = rect.size.width/2.0 
     UIColor.red.setFill() 
     UIColor.blue.setStroke() 
     let bezierPath = UIBezierPath() 
     let centerPoint = CGPoint(x: rect.origin.x + radius, y: rect.origin.y + radius) 
     var thisPoint = CGPoint(x: centerPoint.x + radius, y: centerPoint.y) 
     bezierPath.move(to: centerPoint) 
     var thisAngle: CGFloat = 0.0 
     let sliceDegrees: CGFloat = 360.0/self.beams/2.0 

     for _ in 0..<self.beams { 
      let x = radius * CGFloat(cosf(Float((thisAngle + sliceDegrees).degreesToRadians))) + centerPoint.x 
      let y = radius * CGFloat(sinf(Float((thisAngle + sliceDegrees).degreesToRadians))) + centerPoint.y 
      thisPoint = CGPoint(x: x, y: y) 
      bezierPath.addLine(to: thisPoint) 
      thisAngle += sliceDegrees 
      let x2 = radius * CGFloat(cosf(Float((thisAngle + sliceDegrees).degreesToRadians))) + centerPoint.x 
      let y2 = radius * CGFloat(sinf(Float((thisAngle + sliceDegrees).degreesToRadians))) + centerPoint.y 
      thisPoint = CGPoint(x: x2, y: y2) 
      bezierPath.addLine(to: thisPoint) 
      bezierPath.addLine(to: centerPoint) 
      thisAngle += sliceDegrees 
     } 
     bezierPath.close() 
     bezierPath.lineWidth = 1 
     bezierPath.fill() 
     bezierPath.stroke() 
    } 

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