I dynamically generate a WKT LineString between points in a map layer created for display in OpenLayers. I would like to make the lines between the points curved, and I would like to be able to dynamically change the curvature based on various input variables.
This is a network monitoring application, and we would like the curvature to be based on the delay time between points (and not on the initial delay itself, but on the deviation from the "normal" values ββfor a certain period of time).
Although some GIS applications and databases support the CircularString extension for WKT, OpenLayers knows nothing about this.
Therefore, I need to create a curved line from line segments:
Right now the line of the line is simple:
LINESTRING (hop1_long hop1_lat, hop2_long hop2_lat)
The only way I can define to make the linesegment βbendβ is to insert intermediate points:
LINESTRING (hop1_long hop1_lat, long1 lat1, long2 lat2, ..., hop2_long hop2_lat)
This should be adequate for our application, but I donβt know how to create intermediate points!
I assume that there are known methods / algorithms for generating a βcurvedβ line from line segments in the 2d plane. Does anyone have any ideas on how to do this, or books / articles / online resources that might be helpful?
UPDATE (2010-08-13):
Bezier curves were a ticket, and implementing the basic Bezier algorithm was pretty easy after reading it. But I had to write code to create breakpoints. Here is the PHP code I came across. This assumes the class "Vector2d" with members x and 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));
}