Создайте кривую Безье в Objective C, используя алгоритм Пола де Кастельжо

Я пытаюсь использовать алгоритм Поля де Кастельжо, чтобы нарисовать кривую Безье в качестве домашнего задания, но, похоже, он не идеален, вот коды

- (void)recursive_bezier :(double)x1 :(double)y1
                         :(double)x2 :(double)y2
                         :(double)x3 :(double)y3
                         :(double)x4 :(double)y4
{

  count = count+1;
  // Calculate all the mid-points of the line segments
  //----------------------
  double x12   = (x1 + x2) / 2;
  double y12   = (y1 + y2) / 2;
  double x23   = (x2 + x3) / 2;
  double y23   = (y2 + y3) / 2;
  double x34   = (x3 + x4) / 2;
  double y34   = (y3 + y4) / 2;
  double x123  = (x12 + x23) / 2;
  double y123  = (y12 + y23) / 2;
  double x234  = (x23 + x34) / 2;
  double y234  = (y23 + y34) / 2;
  double x1234 = (x123 + x234) / 2;
  double y1234 = (y123 + y234) / 2;
  
  
  if(isFlat)
  {
    //    // Draw and stop
    //    //----------------------
    [self drawLine:x1 :y1 :x4 :y4];
    
  }
  else
  {
    // Continue subdivision
    //----------------------
    if (count == 5) {
      isFlat=true;
    }

    [self recursive_bezier:x1 :y1 :x12 :y12 :x123 :y123 :x1234 :y1234];
    [self recursive_bezier:x1234 :y1234 :x234 :y234 :x34 :y34 :x4 :y4];
    
    
  }
}

- (void)drawLine :(double)x1 :(double)y1
                 :(double)x4 :(double)y4{
  countDraw = countDraw+1;
  NSLog(@"============%d============",countDraw);
  NSLog(@"x1 = %f y1 = %f",x1, y1);
  NSLog(@"x4 = %f y4 = %f",x4, y4);
   
  UIBezierPath *path = [UIBezierPath bezierPath];
  [path moveToPoint:CGPointMake(x1, y1)];
  
  [path addLineToPoint:CGPointMake(x4, y4)];
  
  CAShapeLayer *shapeLayer = [CAShapeLayer layer];
  shapeLayer.path = [path CGPath];
  shapeLayer.strokeColor = [[UIColor blueColor] CGColor];
  shapeLayer.lineWidth = 2.0;
  shapeLayer.fillColor = [[UIColor clearColor] CGColor];
  
  [self.view.layer addSublayer:shapeLayer];

}

введите здесь описание изображения

Может ли кто-нибудь помочь мне, почему правая сторона не рассчитывается и как сделать кривую гладкой?

PS: я получил алгоритм на Алгоритм кривой Безье


person xeravim    schedule 05.11.2016    source источник
comment
как программист, который заботится только о написании кода, который делает то, что ему нужно, относительно хорошо и эффективно, а не о домашней работе: ваша домашняя работа требует от вас использовать рекурсию здесь? Потому что делать это с циклом for намного эффективнее. (рекурсия тратит время и память на отслеживание стека вызовов, что здесь совершенно не нужно)   -  person Mike 'Pomax' Kamermans    schedule 06.11.2016
comment
Это домашнее задание требует, чтобы оно было рекурсивным. :)   -  person xeravim    schedule 07.11.2016
comment
пожалуйста, сообщите учителю, что это ужасный способ каждой рекурсии;)   -  person Mike 'Pomax' Kamermans    schedule 07.11.2016


Ответы (1)


Проблема в том, что как только для isFlat установлено значение true, дальнейшие сегменты не будут подразделяться должным образом, даже на верхнем уровне. Это потому, что это информация, относящаяся к определенному уровню рекурсивных вызовов, а не что-то глобальное для всего этого. Если вы выполните выполнение кода, это должно быть более ясным.

Лучший способ сделать это - объявить count в качестве параметра int для recursive_bezier и передать 0 на верхнем уровне, когда вы вызываете его, и передать count + 1, когда вы вызываете его рекурсивно. Вы можете избавиться от переменной isFlat и просто проверить count >= 5.

person samgak    schedule 05.11.2016
comment
МОЙ БОГ! Идеально! Я просто забыл, как работает рекурсия, но благодаря этому все вопросы решены. Спасибо чувак! - person xeravim; 05.11.2016