Создание произвольного изогнутого хорошо известного текста LineString для отображения в OpenLayers - PullRequest
2 голосов
/ 09 августа 2010

Я динамически генерирую строку WKT LineString между точками в слое карты, создаваемом для отображения в OpenLayers.Я хотел бы сделать линии между точками изогнутыми, и я хотел бы иметь возможность динамически изменять кривизну на основе различных входных переменных.

Это приложение для мониторинга сети, и мы хотели бы, чтобы кривизна основывалась на временах задержки между точками (не на самой необработанной задержке, а на отклонении от «нормальных» значений в течение заданного периода времени).

Хотя некоторые ГИС-приложения и базы данных поддерживают расширение CircularString для WKT, OpenLayers ничего об этом не знает.

Так что мне нужно сгенерировать изогнутую линию из отрезков линии:

Прямо сейчас строки строки просто:

LINESTRING(hop1_long hop1_lat, hop2_long hop2_lat)

Единственный способ, которым я могуопределить, чтобы сделать отрезок линии «изогнутым», значит вставить промежуточные точки:

LINESTRING(hop1_long hop1_lat, long1 lat1, long2 lat2, ..., hop2_long hop2_lat)

Это должно быть вполне адекватно для нашего приложения, но я не знаю, как генерировать промежуточные точки!

Я предполагаю, что существуют хорошо известные методы / алгоритмы для генерации «изогнутой» линии из отрезков в 2d плоскости.У кого-нибудь есть идеи относительно того, как этого добиться, или книги / статьи / онлайн-ресурсы, которые могут быть полезны?

ОБНОВЛЕНИЕ (2010-08-13):

Кривые Безье были билетом, и реализовать базовый алгоритм Безье было довольно легко после прочтения.Но мне пришлось написать некоторый код для генерации контрольных точек.Вот код PHP, который я придумал.Предполагается, что класс Vector2d состоит из x и y членов.

function get_control_points($to, $from, $mag_scale, $angle) {
  $dirX = $to->x - $from->x;
  $dirY = $to->y - $from->y;

  $mag = sqrt(($dirX * $dirX) + ($dirY * $dirY));
  if (!$mag) {
    return array($to, $from);
  }

  $length = $mag * $mag_scale;

  $dirX = $dirX / $mag;
  $dirY = $dirY / $mag;

  $sin = sin($angle);
  $cos = cos($angle);

  $rotX = $cos * $dirX - $sin * $dirY;
  $rotY = $sin * $dirX + $cos * $dirY;
  $rotNegX = $cos * -$dirX - $sin * $dirY;
  $rotNegY = $sin * $dirX - $cos * $dirY;

  // Flip control points for "backwards" curves
  if ($dirX x;
    $y1 = -$rotNegY * $length + $from->y;
    $x2 = -$rotX * $length + $to->x;
    $y2 = -$rotY * $length + $to->y;
  }
  // Or generate "normal" control points
  else {
    $x1 = $rotX * $length + $from->x;
    $y1 = $rotY * $length + $from->y;
    $x2 = $rotNegX * $length + $to->x;
    $y2 = $rotNegY * $length + $to->y;
  }

  return array(new Vector2d($x2, $y2), new Vector2d($x1, $y1));
}

1 Ответ

3 голосов
/ 10 августа 2010

Если вы хотите создать серию отрезков, которые образуют кривую, начните с просмотра кривых, которые легко параметризуются одной переменной. Например, окружность с центром в (cx, cy) с радиусом r параметризуется следующим выражением:

(x, y) = (cx, cy) + r * (cos (t), sin (t)),

где t работает от 0 до 2 & pi;.

Таким образом, вы можете создать полукруглую форму, скажем, оценивая окружность со значениями t k = & pi; & times; k / 30, где k варьируется от 0 до 30. Это даст вам полукруглая дуга, состоящая из 30 отрезков.

Если вам нужны более общие кривые, посмотрите Кривые Безье . Они параметризованы значением t, которое можно оценить через равные интервалы от 0 до 1.

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