2012-05-01 8 views
5

Estoy buscando una manera de crear estrellas programáticamente, sunburst y otros efectos "puntiagudos" usando UIBezierPath.iPhone iOS Genere estrella, sunburst o polígono UIBezierPath programáticamente

Starburst image

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

¿Hay algoritmos que pueden generar puntos de rayos de sol como las formas mediante programación, sin rutas de superposición?

También estoy interesado en un resplandor solar de forma irregular como la siguiente:

irregular sunburst

me imagino que tal algoritmo tomaría un cierto número de rayos, luego dividir el círculo más o menos en una serie de segmentos y generar puntos para dicho segmento en el sentido de las agujas del reloj. ¿Existe un algoritmo como el que estoy describiendo o tendré que escribir uno solo?

¡Gracias!

Respuesta

6

Sé esto viejo, pero tenía curiosidad acerca de la primera parte de esta pregunta, y al salir de la publicación de jrturton, creé una UIView personalizada que genera un UIBezierPath desde el centro de la vista. Incluso lo animó girando para obtener puntos de bonificación. Aquí está el resultado:

enter image description here

El código que he utilizado es aquí:

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

}

Y se puede descargar un proyecto de ejemplo aquí:

https://github.com/meekapps/Sunburst

2

No conozco un algoritmo para crear estos, pero tengo algunos consejos: cree su camino bezier de modo que (0,0) sea el centro del estallido solar, luego defina todos los puntos que necesite para dibujar uno "haz" de su rayo solar hacia arriba, volviendo a (0,0)

Luego, para tantos haces como desee, realice un ciclo: aplique una transformación de rotación (2 pi/número de haces) a sus puntos de rayo de sol (CGPointApplyTransform) y agréguelos a la ruta.

Una vez que haya terminado, puede traducir y escalar la ruta para el dibujo.

He utilizado un proceso similar para dibujar polígonos de estrellas recientemente y fue muy simple. Crédito a Rob Napier's libro para la idea.

0

Swift versión para este

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

} 
Cuestiones relacionadas