2013-08-22 3 views
16

Я пытаюсь найти способ рисовать iOS 7-стиль значок «squircle» форма программно, используя основную графику. Я не спрашиваю, как нарисовать округленный прямоугольник. Squircle является superelipse:Рисовать iOS 7-стиль squircle программно

Squircle

, который немного отличается от обычного закругленного прямоугольника: Rounded rectangle vs squircle

Music icon in squircle

Это точная формула is readily available. Однако я не могу понять, как это сделать, используя, например, CGPath, не говоря уже о том, чтобы заполнить его и легко изменить его размер. Все это, будучи полностью точным с формулой. Есть идеи?

+0

Нет Я знаю, как сделать закругленный прямоугольник; Я действительно суперэллипсис типа squircle, поскольку они используют для значков трамплинов на iOS 7. –

+2

@RemyVanherweghem. Метод 'bezierPathWithRoundedRect' был изменен в iOS 7, чтобы нарисовать более гладкие углы. Кроме того, это не похоже на шквал: http://blog.mikeswanson.com/post/62341902567/unleashing-genetic-algorithms-on-the-ios-7-icon – millimoose

+0

(Тем не менее, методы 'UIBezierPath' не создавайте идеальное совпадение с шаблоном значков, они просто ближе, чем раньше). – millimoose

ответ

12

цитата из Википедии: Superellipse

при п = 1/2, в частности, каждый из четырех дуг является кривым Безье Квадратичного определяется два оси; в результате каждая дуга является отрезком параболы.

Так почему бы не попытаться приблизиться к Squircle, используя кривые Безье? Обе кривые (Безье и Сквирль) определяются параметрическими уравнениями.

UIBezierPath Class есть метод: addCurveToPoint:controlPoint1:controlPoint2:

присоединяет кубическую Безье кривого пути приемника.

ПРИМЕЧАНИЕ: Использование метода addQuadCurveToPoint:controlPoint: дает худшие результаты - проверено.

Я использовал этот метод, и вот что получилось в результате:

red line - прямоугольник с закругленными углами, blue line - прямоугольник из четверок кривых Безье

Rounded rectangle vs cubic Bezier curve

Если этот результат интересно - рисунок ниже код ,

ПРИМЕЧАНИЕ. Для достижения более точного соответствия кривой Безье может потребоваться изменить координаты четырех corner points (теперь они соответствуют углам прямоугольника, на котором изображена фигура).

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

Отличный ответ. Благодаря! –

2

Это не большой ответ, так как он не получает к сердцу то, что вы спрашиваете, что как рисовать суперэллипс ** программно, но вы можете:

  1. Скачать SVG для значка формы iOS7 здесь: http://dribbble.com/shots/1127699-iOS-7-icon-shape-PSD
  2. Import это ваш Xcode проект
  3. Добавить PocketSVG в свой проект: https://github.com/arielelkin/PocketSVG
  4. Загрузите SVG, и преобразовать его в UIBezierPath, оттуда вы можете масштабировать и трансформировать однако вам нравится:

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

** Это может быть, стоит отметить, что форма не может быть точным суперэллипс все равно: http://i.imgur.com/l0ljVRo.png

0

Это было бы довольно легко сделать в OpenGL ES с шейдером. Просто нарисуйте квад и передайте x и y как атрибуты вершин. В шейдере фрагмента подключите x и y к уравнению. Если результат < = 1, то фрагмент находится внутри формы. Если я смогу получить свободное время, я могу попробовать это и опубликовать здесь.

Если вы хотите использовать CGPath, я думаю, что ключ должен параметризовать x и y в терминах t, который идет от 0 до 2π. Затем оценивайте x и y через регулярные интервалы. Я постараюсь понять это и в свободное время, но моя математика довольно ржавая.

BTW, я уверен, что Apple не, используя эту формулу. См ссылки, которая @millimoose Добавлено: http://blog.mikeswanson.com/post/62341902567/unleashing-genetic-algorithms-on-the-ios-7-icon

Смежные вопросы