Необходим алгоритм расхождения от центра по прямым...

Алгоритмы: от сортировки пузырьком до численных методов

Модераторы: C_O_D_E, DeeJayC

Ответить
chur
Сообщения: 195
Зарегистрирован: 17 фев 2004, 10:44
Откуда: Riga, Latvia

05 апр 2004, 01:08

Вот такой вот алгоритм (perl)
Исходные данные: направление (угол), координаты текущей ячейки (x,y).

Код: Выделить всё

sub nextcell($$$) {
  #получаем исходные данные
  my ($ang, $x, $y) = @_;
  #дополнительные переменные
  my ($K, $dx, $dy);
  my ($temp1, $temp2);

  #проверим, не вертикальное ли направление
  $temp1 = sin($ang);
  if (abs($temp1)==1) { $y+=$temp1; } # если да, то просто увеличиваем y-координату
  else {
    #проверим, не горизантальное ли направление
    #но, в принципе, на горизонтальность можно не проверять
    $temp2 = cos($ang);
    if (abs($temp2)==1) { $x+=$temp2; } # если да, то просто увеличиваем x-координату
    else {
      #определим, в какую сторону изменяется x (влево(-1) или вправо(1))
      $dx = $temp2>0 ? 1 : -1;
      #определим коэффициент прямой и округлим до 12 знаков после запятой.
      $K = sprintf("%.12f", $temp1/$temp2);
      if (abs($K)==1) {  #направление 45 градусов надо обработать отдельно
        if (abs($y) > abs($x)) { $x+=$dx; }
        elsif (abs($x) > abs($y)) { $y+=$K*$dx; }
        elsif (abs($x) % 2) { $x+=$dx; }
        else  { $y+=$K*$dx; }
      }
      else { #общий случай
        #определим, в какую сторону изменяется y (вниз(-1) или вверх(1) если dx = 1 и наоборот)
        $dy = $K>0 ? $dx : -$dx;
        #чтобы найти следующую ячейку, на определить, какую сторону ячейки пересекает прямая "на выходе". Рассмотрим случай когда движимся вправо вверх. Прямая может выйти либо через верхнюю сторону, либо через правую. Определим координату y, в которой прямая пересекает вертикаль, содержащую правую сторону ячейки и сравним с координатой y верхней стороны ячейки. Если больше первое, то прямая выходит через верхнюю сторону, если меньше - через правую. 
        $temp1 = sprintf("%.10f", abs($K * ($x + $dx * 0.5)) - ($y + $dy * 0.5));
        if ($temp1 < 0) { $x += $dx; }
        elsif ($temp1 > 0) { $y += $dy; }
        elsif (abs($K) > 1) { $y += $dy; }
        else { $x += $dx; }
      }
    }
  }
  # возвращем координаты следующей ячейки
  return ($x, $y);
}
chur
Сообщения: 195
Зарегистрирован: 17 фев 2004, 10:44
Откуда: Riga, Latvia

06 апр 2004, 11:04

Нет, это алгоритм рисования якобы прямой.
Например. Начальная ячейка (0,0), угол 1 рад.
Вызываем функцию nextcell(1,0,0) - ответ: следущая ячейка (0,1)
Вызываем функцию еше раз: nextcell(1,0,1) - ответ: (1,1) и т.д.
nextcell(1,1,1) - (1,2)
nextcell(1,1,2) - (2,2)
nextcell(1,2,2) - (2,3)
nextcell(1,2,3) - (2,4)
nextcell(1,2,4) - (3,4)
nextcell(1,3,4) - (3,5)
nextcell(1,3,5) - (4,5)
Аватара пользователя
Naeel Maqsudov
Сообщения: 2551
Зарегистрирован: 20 фев 2004, 19:17
Откуда: Moscow, Russia
Контактная информация:

08 апр 2004, 03:20

Короче надо построить дерево всех кратчайших путей из любой клетки до ценра.

Давайте попробуем так:
Центр известен, углы известны, поле ограничено (Как я понимаю 100x100) Cледовательно, можно
найти точки, находящиеся на краю поля и на лучах проведеных из центра под углами a и b.

Также можно определить все точки лежащие на краю поля между этими двумя точками (Это всегда самые удаленные точки от заданного центра, т.е. точки лежащие на краях поля). Таких точек будет 396, если разница между углами a и b 360 градусов.

Теперь берем алгоритм Брезенхема для построения прямой (самый первый, предложенный в этой дискуссии выше). И начинаем как бы строить отрезки от крайних точе к центру. Присваивая каждой точке номер, вес (уровень), и ссылку на предыдущую точку. НО в этот алгоритм добавим дополнительное условие выхода при попадании в точку, в которой мы уже побывали (ей уже будет присвоен номер, вес и т.д.)

Ну как?
Ответить