Я динамически генерирую строку 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));
}