Алгоритм заливки на кавах с использованием машинописи (angular) - PullRequest
0 голосов
/ 11 апреля 2020

Я пытаюсь реализовать ведро с краской, которое закрашивает форму, создает новую форму и закрывает ее. после некоторого исследования я решил реализовать алгоритм заливки, используя стек. '' '

floodFill(pos: Point2D, stack: Point2D[]): void {
    if (this.stroke.includes(pos)) { return; }
    this.setColor(pos);
    this.stroke.push(pos);
    const cardinalPoints: Point2D[] = [{x: pos.x, y: pos.y - 1}, {x: pos.x + 1, y: pos.y},
                                       {x: pos.x, y: pos.y + 1}, {x: pos.x - 1, y: pos.y}];
    cardinalPoints.forEach( (point) => {
      const color = this.getColor(point);
      if (this.toleranceCheck(color, this.targetColor) && !stack.includes(point)) { stack.push(point); }
    });
    console.log(stack.length);
    const nextPoint = stack.pop();
    if (nextPoint) {this.floodFill(nextPoint, stack); }
  }

' '' Я думаю, что он застрял в рекурсии.

  • setColor устанавливает требуемые пиксели ImageData.data uint8ClampedArray
  • проверка допуска проверяет, находится ли цвет пикселя в пределах [targetColor - (targetColor * допуск), targetColor + (targetColor * допуск)];
  • штрих - это список посещенных точек.
  • стек - это стек точек для проверки Я попытался реализовать его без стека (называя его север / восток / запад / юг), но происходит то же самое.

Исправление для этого - вызов функции через некоторое время l oop, как показано в коде под:

  async onMouseDown(e: MouseEvent): Promise<void> {
await this.getCanvasData();
this.stack.push(new Point2D(e.offsetX, e.offsetY));
this.targetColor = this.getColor(new Point2D(e.offsetX, e.offsetY));
this.visited = [];
this.control.addShape(this.shape);
this.shape.style.strokeWidth = '1';
this.shape.style.primaryColor = this.colors.getPrimaryString();
this.shape.style.secondaryColor = this.colors.getPrimaryString();
while (this.stack.length !== 0) {
  console.log(this.stack.length);
  let point = this.stack.pop();
  while (point && this.visitedIncludes(point)) { point = this.stack.pop(); }
  console.log(this.stack.length);
  if (point) { this.floodFill(point);}
  this.pathify();
}

}

Этот код отлично работает для небольших областей. Но это действительно медленно для больших областей. это может быть оптимизировано?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...