[Tex/LaTex] Asymptote: How to create a radial shading or “elliptical” shading with intermediate color steps

asymptoteshading

In Asymptote I can create radial gradient shadings using the radialshade function which defines a gradient varying smoothly from color A on a circle with center cA and
radius rA to color B on a circle with center cB and radius rB. But I find myself needing to specify intermediate color shades along the way to get the look I want, e.g. to get a circle that has a small white-red area in the center, a larger dark-red outer area, and a pure red area in between. I tried to achieve this by combining two radial shades in the following way:

size(0,100);

path g=scale(2)*unitcircle;
pair A=(0.35,0.35), B=(0.6,0.6), C=(0,0);

radialshade(scale(1.1)*unitcircle,white,C,0,red,C,0.8);
radialshade(scale(1.0)*unitcircle^^g,red+evenodd,C,1,black,C,2);

giving the following output:

This is not bad but I feel that this is not the most elegant way to do it. Furthermore I feel that the transition area, where one radial shading meets the other one, is not as smooth as I would hope.
Another thing I would like to achieve is an "ellipse" equvialent to radialshade but I haven't found a solution for that.

I really like the behavior of TikZ for that sort of thing. Here I can declare a radial shading in such a way that I can give intermediate colors as well as their radial positions. Furthermore the radial shadings also kind of adapt to the shape they are used on so that an ellipse is shaded in an elliptical way. Also there is some nice way of distorting the shading by specifying a center different from {0, 0} which is quite handy in some situations (but, of course, this effect can be achieved with radialshade too).
Example:

\documentclass{standalone}

\usepackage[svgnames]{xcolor}
\usepackage{tikz}

\pgfdeclareradialshading{normal}{\pgfqpoint{0bp}{0bp}}{%
  color(0bp)=(white);
  color(10bp)=(red!90!black);
  color(20bp)=(black!75!red);
  color(30bp)=(black);
  color(100bp)=(black)}

\pgfdeclareradialshading{distorted}{\pgfqpoint{10bp}{10bp}}{%
  color(0bp)=(white);
  color(10bp)=(red!90!black);
  color(20bp)=(black!75!red);
  color(30bp)=(black)}

\begin{document}

\begin{tikzpicture}
  \shade [shading=normal] (-1, 3.5) circle (1.5cm);
  \shade [shading=distorted] (3, 3.5) circle (1.5cm);
  \shade [shading=normal] (-3, 0) ellipse (2 and 1.5);
  \shade [shading=distorted] (2.00, 0.0) ellipse (2 and 1.5);
  \shade [shading=normal] (5.00, -1.5) rectangle (7, 1.5);
\end{tikzpicture}

\end{document}

enter image description here

What is the best way to achieve the look of the TikZ examples?

Best Answer

How's this?

enter image description here

settings.outformat="pdf";
size(5cm);
import graph;

pen[] pens = new pen[] {white, 0.9*red + 0.1*black, 0.75*black + 0.25*red, black};
path outerpath = ellipse((0,0), 2, 1.5);
path innerpath = (1,0.8);

path midpath(path p1, path p2, real t) {
  pair f(real s) {
    return (1-t)*relpoint(p1, s) + t*relpoint(p2, s);
  }
  path p = graph(f, 0, 1, operator ..) -- cycle;
  return p;
}

int lastpath = pens.length - 1;
path[] paths = new path[lastpath + 1];
for (int i = 0; i <= lastpath; ++i) {
  paths[i] = midpath(innerpath, outerpath, i/lastpath);
}

draw(paths, pens);
Related Question