Как добавить скругленный угол на неправильную фигуру?

Я хочу обойти каждый уголок этого. Я использую UIBezierPath для рисования и установки

path.lineCapStyle = kCGLineCapRound;
path.lineJoinStyle = kCGLineJoinRound;

это не работает.

У меня есть удобный способ сделать это вместо последовательности addLineToPoint и addArcWithCenter

Как добавить скругленный угол на неправильную фигуру?

В пользовательском представлении

- (void)drawRect:(CGRect)rect {

    UIBezierPath *path = [UIBezierPath bezierPath];
    [path moveToPoint:CGPointMake(100, 100)];
    [path addLineToPoint:CGPointMake(150, 100)];
    [path addLineToPoint:CGPointMake(150, 150)];
    [path addLineToPoint:CGPointMake(200, 150)];
    [path addLineToPoint:CGPointMake(200, 200)];
    [path addLineToPoint:CGPointMake(250, 200)];
    [path addLineToPoint:CGPointMake(250, 250)];
    [path addLineToPoint:CGPointMake(100, 250)];
    [path closePath];
    path.lineCapStyle = kCGLineCapRound;
    path.lineJoinStyle = kCGLineJoinRound;

    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSaveGState(context);
    CGContextSetFillColorWithColor(context, UIColor.greenColor.CGColor);
    CGContextAddPath(context, path.CGPath);
    CGContextFillPath(context);
    CGContextRestoreGState(context);
}

В Viewcontroller

- (void)viewDidLoad {
    [super viewDidLoad];
    testvvv *test = [[testvvv alloc] initWithFrame:self.view.bounds];
    [self.view addSubview:test];
}
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
126
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Вы можете добавить закругленный угол в траекторию Безье, используя метод ниже.

path.addArcWithCenter(CGPoint(x: 300-10, y: 50), radius: 10 , startAngle: 0 , endAngle: CGFloat(M_PI/2)  , clockwise: true)

Да, он может это сделать, но может быть слишком много линий и дуг для расчета, есть ли удобный способ сделать это?

Henson Fang 31.10.2018 05:40

Добавленный вами код kCGLineCapRound работает нормально.

kCGLineCapRound предназначен для пути, попробуйте добавить немного lineWidth для пути. Вы увидите разницу.

path.lineWidth = 50.0

При необходимости вы можете установить его strokeColor таким же, как цвет заливки.

Очень хороший пост на uibezierpath Рисование UIBezierPath в коде, созданном UIView

@HensonFang, пожалуйста, ссылайтесь на этот пост. Это очень хороший пост на uibezierpath stackoverflow.com/questions/21311880/…

Satish 31.10.2018 06:43
Ответ принят как подходящий

Я думаю, вы этого хотите:

rounded staircase

Есть функции Core Graphics для скругления углов, которые недоступны в UIBezierPath. Это CGContextAddArcToPoint и CGPathAddArcToPoint. Я объясню, как они работают.

Сначала давайте рассмотрим, как вы рисуете две линии, пересекающиеся в остром углу. Когда путь инициализируется впервые, его «текущая точка» находится в начале координат:

current point at origin

Вы используете CGPathMoveToPoint для перехода к началу первой строки в (x0, y0):

after move

Затем вы используете CGPathAddLineToPoint, чтобы нарисовать первую линию, заканчивающуюся углом на (x1, y1):

after first line

Наконец, вы снова используете CGPathAddLineToPoint, чтобы провести вторую линию к (x2, y2):

after second line

Теперь давайте воспользуемся CGPathAddArcToPoint, чтобы вместо этого закруглить угол. Перемотайте назад сразу после того, как вы использовали CGPathMoveToPoint для перехода к началу первой строки:

after move

CGPathAddArcToPoint принимает точки два: точка в углу (которая не будет достигнута, так как она будет закругляться) и следующая точка в форме после угла. Таким образом, вы передаете ему как (x1,y1) (угол), так и (x2,y2) (конец следующей строки). Вы также передаете ему радиус угла:

after first line and corner

Обратите внимание, что CGPathAddArcToPoint рисует для вас первую линию и дугу, образующую закругленный угол, и оставляет текущую точку в конце этой дуги. Затем вы используете CGPathAddLineToPoint, чтобы нарисовать вторую линию:

after second line

Хорошо, это объясняет (я надеюсь), как работает CGPathAddArcToPoint. CGContextAddArcToPoint работает таким же образом, но работает на пути контекста.

Чтобы применить это к форме лестницы, вы хотите использовать функцию CG*AddArcToPoint для рисования каждого угла. Поскольку у вас замкнутая форма и вам не нужны острые углы, вам вообще не нужно использовать CG*AddLineToPoint. Вы можете использовать функцию дуги, чтобы рисовать каждую линию, а также закругленные углы.

Одна вещь, о которой нужно помнить, - это то, с чего вы начинаете форму. Вы не можете начинать с угла, потому что тогда вы получите прямую линию из угла. Вместо этого проще всего начать с середины одной из линий, подальше от любого угла.

Кроме того, поскольку вы делаете это в drawRect:, вы можете просто использовать путь контекста вместо создания отдельного объекта UIBezierPath или CGPath. Вот код, который я использовал, чтобы нарисовать результат выше:

- (void)drawRect:(CGRect)rect {
    CGPoint p[] = {
        {100, 100},
        {150, 100},
        {150, 150},
        {200, 150},
        {200, 200},
        {250, 200},
        {250, 250},
        {100, 250},
    };
    size_t count = (sizeof p) / (sizeof p[0]);
    CGPoint pLast = p[count - 1];

    CGContextRef gc = UIGraphicsGetCurrentContext();

    // Start at the midpoint of one of the lines.
    CGContextMoveToPoint(gc, 0.5 * (pLast.x + p[0].x), 0.5 * (pLast.y + p[0].y));

    for (size_t i = 1; i < count; ++i) {
        CGContextAddArcToPoint(gc, p[i-1].x, p[i-1].y, p[i].x, p[i].y, 10);
    }
    CGContextAddArcToPoint(gc, pLast.x, pLast.y, p[0].x, p[0].y, 10);

    // Connect the last corner's arc to the starting point.
    CGContextClosePath(gc);

    [UIColor.greenColor setFill];
    CGContextFillPath(gc);
}
{22, 104.33333333333333}, {22, 135.33333333333334}, {23.333333333333332, 136.33333333333334}, {23.333333333333332, 167.33333333333334}, {351, 167.33333333333334}, {351, 136.33333333333334}, {352, 135.33333333333334}, {352, 104.33333333333333}, если я перейду на этот массив прямоугольников, форма пойдет не так
Henson Fang 06.11.2018 05:10

Выложите, пожалуйста, новый отдельный вопрос с изображением проблемы.

rob mayoff 06.11.2018 05:26

Другие вопросы по теме