Bezier curves

From OpenStreetMap Wiki
Jump to: navigation, search

A bézier curve is a mathematical approach for modelling smooth curves that can be scaled indefinitely. They are often used in in vector based computer graphics e.g. for modelling the curved roads of a map. This page should document current use within OpenStreetMap and potential future use.

SVG curved lines

Barry Crabtree (User:Dotbaz) experimented with modifying Osmarender to output some segments as curves instead of lines (curved lines in SVG). This was back in 2006/2007. This was since set up as a lines2curves.pl script used by tiles@home (so bezier curves are appearing on the 'Osmarender' layer). See Osmarender/BezierCurves (TODO resolve duplication)

Example:

Before (straight line segments) After (using bezier curves)
Motorway-intersection-before.png Motorway-intersection-after.png

Some points about using beziers (appropriately).

  • Using bezier curves make the map more accurate - in most cases the bezier approximation between points is closer in reality than a linear approximation between points. How often in roads do you see sharp angular changes?
  • The curves make the map look more attractive. No, this isn't a flippant point. Its a form & function thing. A map that 'looks' better while performing the same function is more likely to be used.
  • The curves remove the sharp angular changes. The effect of this is that the person viewing the maps sees the topology of the map as it is meant to be seen, and is not detracted by the angular artifacts of the straight-line approximation. The eye seems to be drawn to the angular joins and it shouldn't be. The eye should be drawn to the relevant parts of the map.

Writing our own / using libraries

It might be good to write our own. For example processing can draw the curve but AFAIK it can't position and rotate text on top of it so, which we need.

Text on curves in Processing isn't totally trivial, but it provides helper methods to assist with working out where the curve is according to the parameter: for Catmull-Romm splines, for Bezier splines.

Disabling bezier curves

To disable the bezier curves for some ways (e.g. power lines, aerialways) add no-bezier as a css class in the style file.

Built-in Support

unknown support

  • ImageMagick
  • GD
  • Java AWT
  • Illustrator
  • PDF
  • DXF

Quadratic only

  • Flash

Cubic only

  • PostScript
  • Cairo
  • Processing (the library on the applet) (not sure about cubic, but definitely does either Bezier or Catmull-Rom with detail settings for optimised drawing and helper functions for calculating positions along the curve.)
    • Erm, I think Bezier and CR curves are both cubic... Timmmm 10:35, 2 July 2008 (UTC)

both

  • SVG http://www.w3.org/TR/SVG11/paths.html#PathDataCubicBezierCommands
  • Java Swing 2D does cubic and quadric and a mixture.
  • Safari/Firefox <canvas> HTML element. See: [1] [2] [3]
  • CGAL has bezier curve support as part of their arrangement_2 package. This package and the ones built on top of it (boolean polygon operations) provide a robust set of utilities to do polygon operations on bezier curves. For software that needs to validate OSM data (e.g. do two ways overlap, intersect, etc.) CGAL sovles this problem. CGAL is available freely in a GPL-like license and is C/C++ so it might not be useful to a significant part of existing OSM software that would need bezier curve support.

Discussions

Several mailing list discussions back in early 2007 including :

2007-January - (dev) Drawing ways with bezier curves rather than line segments

Bezier curves have not been discussed so much recently. Please update the page with current statuses if you know more

Links

Not automatically but add it to the API

I think it would be better to add such a feature to the API directly. So I wouldn't have to draw 10 nodes for a curve that will then be rendered as a real curve but I would draw one node at each end plus two as a reference for drawing the bezier curve. That way the renderer would know where to make curves and where not (and we wouldn't need error-prone magic). And, as I said, we'd need a lot less nodes. Have a look at Inkscape, there you can make nodes (each one seperately) smooth, that way it will ensure that the bezier nodes on both sides of a node are in excactly opposite direction (See [4]). This way we would avoid the annoying problem that when we add a little street branching off a street, there will be a little corner. What do you think? --Bkr 15:16, 4 June 2008 (UTC)

Bezier api.png

One way this could be done is to insert control points between nodes in a way's node list.

<way>
  <nd ref="1"/>
  <cp ref="2"/>
  <nd ref="3"/>
  <cp ref="4"/>
  <cp ref="5"/>
  <nd ref="6"/>
  <nd ref="7"/>
</way>

In this example nodes 1 and 3 are connected through control point 2 (a quadratic); nodes 3 and 6 are connected through control points 4 and 5 (a cubic); and nodes 6 and 7 form a straight line (no control points between). More control points could be added in the future for higher-order curves. For now the API could limit it to only quadratic and cubic curves. Control points could be implemented as nodes with lat/lon, but there should be no need to add tags to them.