ASVG - Challenge plots

Explanation

Most graph plotters (like Desmos, Wolfram|Alpha and JSXGraph) do an OK job of plotting certain graphs, but only for a limited domain. Go beyond that domain, and things start to look ugly. Also, if we try to animate the graph, it's often slow because they use a lot of points (and therefore a lot of calculations are involved).

See what I mean here:

On this ASVG page, the aim is to produce graphs that really do work "to infinity" (within the constraints of Javascript's number and calculation limits), and animate smoothly.

This is achieved by one or more of the following techniques:

  1. Using the least number of points possible to produce a smooth curve for the given domain. (This can involve using different spacing between points as necessary.)
  2. Where a graph consists of repeated patterns, we plot just one instance of that pattern (shown as blue when you choose "show colours" below) and "clone" that instance (this is shown as "num. <use>" on each graph, and the clones are red).
  3. We create a new <path> at every discontinuity, so there's no near-vertical join between a "+∞" point and a "−∞" point.
  4. Some portions of these graphs appear to be simply joined (straight) segments, so that's what we use for those portions (shown as orange where used). Why use tens of thousands of points when 2 will do?
  5. When there's a large domain (we are zoomed right out), in each of these graphs there appears to be a solid block, so for those cases we just use a simple polygon with solid colour. No need to plot millions of points that no-one can discern.

Each graph has a "show colours" checkbox. This makes clearer the different sections of each plot and how it's produced (either a simple plot, using <use>, or segments, or a block of solid colour.

ASVG

ASVG is a graph plotter loosely based on Peter Jipsen's ASCIIsvg (no longer under development).

The code for the plots on this page is specific to each graph. That is, these are not "general plots" that Desmos etc can produce for any function. Making these techniques more general is the next challenge.

1. Graph of y = a tan(qx)

In this graph, the animation changes the domain and range, as well as a, the amplitude and q, the multiple of x. The current equation that is being graphed is shown at the top of the graph. You can see various values in the info-box at bottom right, including the number of points used to plot the graph and the number of "clones" (<use>s).

Current graph: y = a tan(ax)

Animate:

2. Graph of y = a tan(qx2)

The almost-vertical curves in this graph get closer together and thinner as x increases and decreases. In this case, we plot one of them, then each clone needs to be scaled in the horizontal direction. The central "U"-shaped portion of this graph is unique, so not cloned.

You can only zoom right in for values within about −500 < x < 500 because of the calculation complications in this graph.

Current graph: y = a tan(ax2)

Animate:

3. Graph of y = a sin(qx)

For this example, we plot just one cycle (from x = 0 to x = 2π, coloured blue if you choose "show colours") and then clone it as many times as needed to cover the domain (shown as red).

When we're zoomed out, the curve starts to look more like segments, so that's what we use (coloured yellow-orange when you choose "show colours"). Zooming out even further gives us an opaque block of colour, and we achieve that by using a simple polygon and filling it with solid colour (in mauve if you choose "show colours").

Current graph: y = a sin(qx)

Animate:

4. Graph of y = ax sin(qx2)

In this graph, the curves get closer together as x increases (or decreases), and the height of each curve portion increases as well.

Similar to the above graphs, we plot the portion that is clearly a curve as normal (shown as blue on the right and magenta on the left), then in places where the curve more closely resembles segments, that's what we use (shown as yellow-orange), and when things get really close together, we employ a solid block of colour (dark orange).

Current graph: y = ax sin(qx2)

Animate:

5. Graph of $ y = \frac{1}{a \sin(qx) + \cos(qx\sqrt{3})} $

This next graph is a strange example since nothing is repeated so we can't make use of cloning.

We do, however, make use of simplifying the plot wherever the curve segements are particularly narrow. You can see this more clearly if you choose "show colours", where the simplified curve portions are shown in light blue.

Current graph:

$$ y = \frac{1}{a \sin(qx) + \cos(qx\sqrt{3})} $$

Animate:

6. Graph of a Fourier series

Our final example is a Fourier Series, showing the approximation for a square wave. Of particular interest in this example is the "spikes" at the extermities of the near-vertical segments, a situation called "Gibbs phenomenon" (which was originally thought to be an error in the graph plotting procedure until it was realised it's inevitable. See Gibbs phenomenon).

In this example we first animate the sums of the sine curves with ever decreasing amplitude and period, to illustrate what's happening, then we animate the domain. We make use of the solid colour technique when we're zoomed out sufficiently far.

Current graph:

$$ y = \frac{10}{\pi} \sum_{i=1}^{100}\frac{1}{2i-1}\sin\left(\frac{(2i-1)\pi}{4}\right) $$

Animate:

Once again, here's what these graphs look like in the "major" graph plotters: