Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 05.09.2010, 18:15   #1
Marsel737
Форумчанин
 
Аватар для Marsel737
 
Регистрация: 09.11.2009
Сообщений: 669
По умолчанию Очень большой цикл, как оптимизировать?

Всем доброго времени суток. Вот такая вот процедура для определения площади двух пересекающихся фигур, сначала я проверяю пересекаются ли они и если пересекаются начинаю определять площадь и закрашивать ту часть площадь которой определяю. Работает очень долго, потому что площадь может доходить до 1000000, получается два цикла от 1 до 1000000

Код:
procedure TfrmMain.GetFigureSquare;
var
  I, J, K: integer;
  LinLength: integer;
  Crossing: boolean;
  CycleBreak: boolean;
begin
  FigSquare := 0;
  LinLength := 0;
  Crossing := false;
  CycleBreak := false;
  if (CoordK.X < CoordB.X) and ((CoordB.Y > CoordK.Y) or
    (CoordA.Y < CoordL.Y)) then
  begin
    Application.MessageBox(PChar('Фигуры не замкнуты'), PChar('Информация'),
      MB_OK + MB_ICONINFORMATION);
    edtFigSquare.Clear;
    Exit;
  end;
  
  { Проверка на пересечение фигур }
  for J := CoordA.Y + 1 to CoordB.Y - 2 do
  begin
    if CycleBreak then
      Break;
    for I := CoordA.X + 1 to CoordB.X - 2 do
    begin
      if imgCanvas.Canvas.Pixels[I, J] = clRed then
      begin
        Crossing := true;
        CycleBreak := true;
        Break;
      end;
    end;
  end;
  
  { Подсчёт пикселей }
  if Crossing then
  begin
    for J := CoordA.Y + 1 to CoordB.Y - 2 do
    begin
      FigSquare := FigSquare + LinLength;
      LinLength := 0;
      { Это можно пропустить
      if imgCanvas.Canvas.Pixels[CoordA.X + 1, J] = clRed then
      begin
        begin
          for K := J + 4 to CoordB.Y - 2 do
          begin
            if imgCanvas.Canvas.Pixels[CoordA.X + 1, K] = clRed then
            begin
              //
            end;
          end;  
        end;
        edtFigSquare.Text := IntToStr(FigSquare);
        Exit;
      end;
      }
      for I := CoordA.X + 1 to CoordB.X - 2 do
      begin
        Inc(LinLength);
        if imgCanvas.Canvas.Pixels[I, J] = clRed then
        begin
          Crossing := true;
          Break;
        end;
        imgCanvas.Canvas.Pixels[I, J] := $006BEB65;
      end;
    end;
    edtFigSquare.Text := IntToStr(FigSquare);
  end else
  begin
    Application.MessageBox(PChar('Фигуры не замкнуты'), PChar('Информация'),
      MB_OK + MB_ICONINFORMATION);
    edtFigSquare.Clear;
  end;
end;
Когда делаю так, вылазит ошибка First chance exception at $75C3B727. Exception class EStackOverflow with message 'Stack overflow'. Process LabWork.exe (2976)

Код:
procedure TfrmMain.GetFigureSquare;
const
  Max = 1000000;
var
  I, J, K: integer;
  LinLength: integer;
  PointCount: integer;
  Crossing: boolean;
  CycleBreak: boolean;
  Points: array[1..Max] of TPoint;
begin
  FigSquare := 0;
  LinLength := 0;
  PointCount := 0;
  Crossing := false;
  CycleBreak := false;
  if (CoordK.X < CoordB.X) and ((CoordB.Y > CoordK.Y) or
    (CoordA.Y < CoordL.Y)) then
  begin
    Application.MessageBox(PChar('Фигуры не замкнуты'), PChar('Информация'),
      MB_OK + MB_ICONINFORMATION);
    edtFigSquare.Clear;
    Exit;
  end;
  
  for J := CoordA.Y + 1 to CoordB.Y - 2 do
  begin
    FigSquare := FigSquare + LinLength;
    LinLength := 0;
    for I := CoordA.X + 1 to CoordB.X - 2 do
    begin
      Inc(LinLength);
      if imgCanvas.Canvas.Pixels[I, J] = clRed then
      begin
        Crossing := true;
        Break;
      end;
      Inc(PointCount);
      Points[PointCount] := Point(I, J);
    end;
  end;
  edtFigSquare.Text := IntToStr(FigSquare);
  for I := 1 to PointCount do
  begin
    imgCanvas.Canvas.Pixels[Points[I].X, Points[I].Y] := $006BEB65;
  end;
end;
Я не всегда знаю, о чем говорю, но знаю, что прав. © Мухаммед Али.
К чёрту обстоятельства. Я создаю возможности. © Брюс Ли
Marsel737 вне форума Ответить с цитированием
Старый 05.09.2010, 18:38   #2
BOBAH13
Android Developer
Старожил Подтвердите свой е-майл
 
Аватар для BOBAH13
 
Регистрация: 19.02.2007
Сообщений: 3,708
По умолчанию

Расчеты выносятся в дочерние потоки.
BOBAH13 вне форума Ответить с цитированием
Старый 05.09.2010, 19:44   #3
Marsel737
Форумчанин
 
Аватар для Marsel737
 
Регистрация: 09.11.2009
Сообщений: 669
По умолчанию

Пнт, а конкретно по коду как оптимизировать? Почему во втором случае происходит переполнение стека?
Я не всегда знаю, о чем говорю, но знаю, что прав. © Мухаммед Али.
К чёрту обстоятельства. Я создаю возможности. © Брюс Ли
Marsel737 вне форума Ответить с цитированием
Старый 06.09.2010, 10:08   #4
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Извиняюсь, а что за условия задачи? Как фигуры заданы, ибо определять попиксельно это все равно что на гусеницах по брущатке камни считать.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Цикл по времени - Как сделать так чтобы цикл выполнялся к примеру 10 секунд ? Anarki Общие вопросы C/C++ 3 13.11.2009 19:23
Как "протянуть" формулу без мыши, если столбец очень большой? zazuza Microsoft Office Excel 7 25.09.2008 10:19
Очень БОЛЬШОЙ вопрос про кодировки в базе Tanuska___:) БД в Delphi 3 02.05.2008 05:36
Цикл с предусловием. ( цикл while) Цикл с постусловием. (цикл repeat ... until) Mr.User Помощь студентам 9 23.11.2007 01:34