Rudie
Rudie

Reputation: 53821

How to draw a smooth path across points around a circle

This might be a math question... I have a set of points on a circular axis. Let's call the circle x and the radius of the points y. The problem is twofold:

  1. I want a smooth line across all points. Let's assume it's a normal x/y graph: I know the exact coordinates. Now how do I create a smooth path between all those points?
  2. It's not a normal x/y graph. It's an a/r graph (angle/radius). The solution from 1. could be applied, I guess, but where do I draw that line? (I'm not sure it being an a/r graph makes it any more difficult.)

(I want to create this on a <canvas> with Javascript. I've set up something for the eager: http://jsfiddle.net/rudiedirkx/5LfdP/1/)

What I'm looking for is

smooth line graph

wrapped around a circle with the ends meeting (so 0% = 350 and 100% = 350).

It feels like a cubic bezier is necessary to create the smooth paths between points, but that's all I got. This is the bezier function I usually use.

Am I making any sense? I can't find a better picture. (Probably because I've no idea what it's called.)

Edit 1: My attempt at a drawing of how it would look: http://www.sketchtoy.com/26800595 (forget the animation, that's just how sketchtoy works)

Edit 2: I've updated my fiddle demo using quadraticCurveTo(), but that's not good enough. I need bezier curves and twice as much to make the curve go THROUGH the points. Like in About Spline Interpolation but hopefully simpler.

Upvotes: 3

Views: 1457

Answers (1)

If you have the function expression for your graph, you can simply plot it turning your coordinates into polar coordinates with a circular offset. Treating 'x' as your angle (with min_x being angle "0" and max_x being angle "360", or for computers, "2π"), using these mappings:

φ (the angle) = map x from interval (min_x,max_x) to interval (0,2π);
a (the amplitude) = map y from (min_y,max_y) to (0, max_distance);

You can then the x/y coordinates you want your function plotted is:

nx = a * cos(φ);
ny = a * sin(φ);

And for graph plotting, I can strongly recommend building a lookup table for your values, so you can bypass having to constantly compute the original x/y values. If you don't have a function, but just a series of points, then you effectively already have this LUT.

After transforming your LUT x/y coordinates, drawing a nice looking curve through each of them is probably a job for a Catmull-Rom spline, not a Bezier, since Catmull-Rom splines go through each point you use, whereas Bezier curves don't, they skirt around every point except the start and end point, so they're unsuited for what you want to do.

Upvotes: 2

Related Questions