Отказ от ответственности

Отказ от ответственности

Итак, вы уже знаете TikZ и/или PSTricks, но хотели бы расширить свои знания, изучив также Asymptote? Вот ваш шанс.

Задача/вопрос:Найдите пример впечатляющей диаграммы, нарисованной с помощью TikZ или PSTricks (в идеале, но не обязательно, ту, которую вы создали сами), и перерисуйте ее с помощью Asymptote. Ваша перерисованная версия должна быть как минимум такой же хорошей, как и оригинал, за исключением того, что 3D-изображения Asymptote могут быть растровыми изображениями высокого разрешения, даже если оригинал был векторным рисунком. Вы должны включить, как минимум, ссылку на оригинал; в идеале вы должны включить (если это разрешено авторским правом) исходный код оригинала и его изображение. Я надеюсь, что в конечном итоге ответы на этот вопрос станут полезным ресурсом для пользователей TikZ и PSTricks, стремящихся изучить Asymptote.

Чтобы сделать сделку более приятной, я обещаю вознаграждение в размере500 очков репутациина самый впечатляющий ответ. «Самый впечатляющий» будет определен путем голосования на момент окончания вознаграждения, хотя я оставляю за собой право дисквалифицировать ответы, которые, по моему мнению, нарушают букву или дух исходного вопроса.

Дополнительный, полуэгоистичный мотив: Пожалуйста, дайте мне знать, если вы найдетемой учебник по асимптотеполезный. Другие потенциально полезные ресурсы включаютофициальная документацияиэтот урок на французском языке по 3D-материалам.


Если вы хотите ответить на этот вопрос, но вам нужны более конкретные примеры, попробуйте перевести ответы сэтот вопрос по рисованию яйцаилиэтот вопрос по рисованию рождественской елки.

решение1

Для начала, вот пример, который я сделал, когда впервые изучал Asymptote. Оригинальная картинка TikZ (взятая из Лекции 2эти заметки класса) находится слева; асимптотный перенос — справа.

введите описание изображения здесь

Код ниже. Обратите внимание, что перевод немного более тщательный, чем необходимо, — например, я не ожидаю, что большинство ответов будут беспокоиться об изменении ширины линии по умолчанию с 0,5pt на 0,4pt. Он также менее тщательный, чем мог бы быть: кончики стрелок не идентичны, как и высота меток.

\documentclass[margin=10pt]{standalone}
\usepackage{tikz}
\usepackage[squaren]{SIunits}
\usepackage[inline]{asymptote}

\begin{document}
\begin{asydef}
    defaultpen(fontsize(10pt));
\end{asydef}
\begin{tikzpicture}[scale=4.0, axes/.style={thick,->}]
    \draw[axes] (-1.2,0) -- (1.2,0) node[right] {$x$};
    \draw[axes] (0,-1.2) -- (0,1.2) node[above] {$y$};

    \draw (0,0) circle[radius=1];

    \draw[->] (0.2,0) node[above right]{$\scriptstyle t~\rad$} arc[start angle=0, end angle=30, radius=0.2];
    \draw[->] (1.07,0) arc[start angle=0, end angle=30, radius=1.07] node[right]{$t$};
    \draw (0,0) -- node[below]{$\Delta x = \cos t$} ({sqrt(3)/2},0) 
        -- node[right,fill=white]{$\Delta y = \sin t$} ({sqrt(3)/2},0.5) 
        -- cycle;
    \path (0,0) -- node[above]{$1$} ({sqrt(3)/2},0.5);
\end{tikzpicture}

\begin{asy}
    unitsize(4cm);
    pen tikzthick = linewidth(0.8pt);
    defaultpen(linewidth(0.4pt));       // This sets the default pen width to 0.4pt to match TikZ; in Asymptote, the default width is 0.5pt.

    draw((-1.2,0)--(1.2,0), arrow=Arrow(TeXHead), L=Label("$x$",EndPoint), p=tikzthick);
    draw((0,-1.2)--(0,1.2), arrow=Arrow(TeXHead), L=Label("$y$",EndPoint), p=tikzthick);

    draw(circle(c=(0,0), r=1));

    draw(arc(c=(0,0), r=0.2, angle1=0, angle2=30),
        arrow=Arrow(TeXHead), 
        L=Label("$\scriptstyle t~\rad$",position=BeginPoint,align=NE) );
    draw(arc(c=(0,0), r=1.07, angle1=0, angle2=30),
        arrow=Arrow(arrowhead=TeXHead),
        L=Label("$t$",position=EndPoint,align=E) );
    path triangle = (0,0)--(sqrt(3)/2,0)--(sqrt(3)/2,1/2)--cycle;
    draw(triangle);
    label(subpath(triangle,0,1), L="$\Delta x = \cos t$", align=S);
    label(subpath(triangle,1,2), L="$\Delta y = \sin t$", align=E, filltype=Fill(white));
    label(subpath(triangle,2,3), L="$1$", align=N);
\end{asy}
\end{document}

решение2

Украдено из ответов на этот вопрос3D спиральный тор со скрытыми линиями. Речь идет о спирали, обернутой вокруг другой спирали, которая также обернута вокруг тора. Позвольте мне назвать это вторым порядком спирали, обернутой вокруг тора, просто для простоты при упоминании этого.

Решение Герберта Фосса с всемогущим PSTricks

\documentclass[pstricks,border=12pt]{standalone}
\usepackage{pst-solides3d}
\begin{document}
\begin{pspicture}[solidmemory](-6.5,-3.5)(6.5,3)
\psset{viewpoint=30 0 15 rtp2xyz,Decran=30,lightsrc=viewpoint}
\psSolid[object=tore,r1=5,r0=1,ngrid=36 36,tablez=0 0.05 1 {} for,
          zcolor= 1 .5 .5 .5 .5 1,action=none,name=Torus]
\pstVerb{/R1 5 def /R0 1.2 def /k 20 def /RL 0.15 def /kRL 40 def}%
\defFunction[algebraic]{helix}(t)
     {(R1+R0*cos(k*t))*sin(t)+RL*sin(kRL*k*t)}
     {(R1+R0*cos(k*t))*cos(t)+RL*cos(kRL*k*t)}
     {R0*sin(k*t)+RL*sin(kRL*k*t)}
\psSolid[object=courbe,
        resolution=7800,
        fillcolor=black,incolor=black,
        r=0,
        range=0 6.2831853,
        function=helix,action=none,name=Helix]%
\psSolid[object=fusion,base=Torus Helix,grid]
\end{pspicture}
\end{document}

введите описание изображения здесь

Решение Чарльза Стаатса с всемогущей Асимптотой

settings.outformat = "png";
settings.render = 16;
settings.prc = false;
real unit = 2cm;
unitsize(unit);

import graph3;

void drawsafe(path3 longpath, pen p, int maxlength = 400) {
  int length = length(longpath);
  if (length <= maxlength) draw(longpath, p);
  else {
    int divider = floor(length/2);
    drawsafe(subpath(longpath, 0, divider), p=p, maxlength=maxlength);
    drawsafe(subpath(longpath, divider, length), p=p, maxlength=maxlength);
  }
}

struct helix {
  path3 center;
  path3 helix;
  int numloops;
  int pointsperloop = 12;
  /* t should range from 0 to 1*/
  triple centerpoint(real t) {
    return point(center, t*length(center));
  }
  triple helixpoint(real t) {
    return point(helix, t*length(helix));
  }
  triple helixdirection(real t) {
    return dir(helix, t*length(helix));
  }
  /* the vector from the center point to the point on the helix */
  triple displacement(real t) {
    return helixpoint(t) - centerpoint(t);
  }
  bool iscyclic() {
    return cyclic(helix);
  }
}

path3 operator cast(helix h) {
  return h.helix;
}

helix helixcircle(triple c = O, real r = 1, triple normal = Z) {
  helix toreturn;
  toreturn.center = c;
  toreturn.helix = Circle(c=O, r=r, normal=normal, n=toreturn.pointsperloop);
  toreturn.numloops = 1;
  return toreturn;
}

helix helixAbout(helix center, int numloops, real radius) {
  helix toreturn;
  toreturn.numloops = numloops;
  from toreturn unravel pointsperloop;
  toreturn.center = center.helix;
  int n = numloops * pointsperloop;
  triple[] newhelix;
  for (int i = 0; i <= n; ++i) {
    real theta = (i % pointsperloop) * 2pi / pointsperloop;
    real t = i / n;
    triple ihat = unit(center.displacement(t));
    triple khat = center.helixdirection(t);
    triple jhat = cross(khat, ihat);
    triple newpoint = center.helixpoint(t) + radius*(cos(theta)*ihat + sin(theta)*jhat);
    newhelix.push(newpoint);
  }
  toreturn.helix = graph(newhelix, operator ..);
  return toreturn;
}

int loopfactor = 20;
real radiusfactor = 1/8;
helix wrap(helix input, int order, int initialloops = 10, real initialradius = 0.6, int loopfactor=loopfactor) {
  helix toreturn = input;
  int loops = initialloops;
  real radius = initialradius;
  for (int i = 1; i <= order; ++i) {
    toreturn = helixAbout(toreturn, loops, radius);
    loops *= loopfactor;
    radius *= radiusfactor;
  }
  return toreturn;
}

currentprojection = perspective(12,0,6);

helix circle = helixcircle(r=2, c=O, normal=Z);

/* The variable part of the code starts here. */
int order = 2;    // This line varies.
real helixradius = 0.5;
real safefactor = 1;
for (int i = 1; i < order; ++i)
  safefactor -= radiusfactor^i;
real saferadius = helixradius * safefactor;

helix todraw = wrap(circle, order=order, initialradius = helixradius, loopfactor=40);    // This line varies (optional loopfactor parameter).

surface torus = surface(Circle(c=2X, r=0.99*saferadius, normal=-Y, n=32), c=O, axis=Z, n=32);
material toruspen = material(diffusepen=gray, ambientpen=white);
draw(torus, toruspen);

drawsafe(todraw, p=0.5purple+linewidth(0.6pt));  // This line varies (linewidth only).

введите описание изображения здесь

О руководстве Чарльза Стаатса

Урок, который я считаю прекрасным, другие люди также могут считать полезным. (Donut E. Knot)

решение3

Отказ от ответственности

Это первая фотография, которую я сделал с помощью asymptote, поэтому, пожалуйста, прокомментируйте.

Я адаптировал tikzответ, который когда-то давал здесь:Построить базовое комплексное преобразование в LaTeX

Код TikZ

\documentclass[tikz]{standalone}
\usetikzlibrary{decorations.markings}
\tikzset{
    arrow inside/.style = {
        postaction = {
            decorate,
            decoration={
                markings,
                mark=at position 0.5 with {\arrow{>}}
            }
        }
    }
}
\begin{document}
\begin{tikzpicture}[>=latex,scale=1.5]
    \begin{scope}
        % Axes
        \draw (0,0) node[below left] {$O$}
            (-0.5,0) -- (4,0) node[below] {$x$}
            (0,-0.5) -- (0,3) node[left] {$y$};
        % Ticks
        \draw (1,0) -- (1,-0.1) node[below] {$a$}
            (3,0) -- (3,-0.1) node[below] {$b$}
            (0,1) -- (-0.1,1) node[left] {$c$}
            (0,2) -- (-0.1,2) node[left] {$d$};
        % Square
        \draw[thick] (1,1) node[below left] {$A$} --
            (3,1) node[below right] {$B$} --
            (3,2) node[above right] {$C$} --
            (1,2) node[above left] {$D$} -- cycle;
        \draw[arrow inside] (1.5,1) -- (1.5,2);
    \end{scope}

    \begin{scope}[xshift=6cm]
        % Axes
        \draw (0,0) node[below left] {$O$}
            (-0.5,0) -- (4,0) node[below] {$u$}
            (0,-0.5) -- (0,3) node[left] {$v$};
        %Help Lines
        \draw (0,0) -- (30:3) (0,0) -- (70:3);
        % Angles 
        \draw[->] (0.6,0) arc[start angle=0, end angle=70, radius=0.6] node[above right] {\small $\phi = d$};
        \draw[->] (0.8,0) node[above right] {\small$\phi = c$} arc[start angle=0, end angle=30, radius=0.8];
        % Transformation
        \draw[thick] (30:1.5) node[right] {$A'$} --
            (30:3) node[below right] {$B'$} arc[start angle=30, end angle=70, radius=3]
            (70:3) node[above right] {$C'$} --
            (70:1.5) node[above left] {$D'$} arc[start angle=70, end angle=30, radius=1.5];
        \draw[arrow inside] (30:1.9) arc[start angle=30, end angle=70, radius=1.9];
    \end{scope}
\end{tikzpicture}
\end{document}

введите описание изображения здесь


Асимптотный код

\documentclass{standalone}
\usepackage[inline]{asymptote}
\begin{document}
\begin{asy}
    import geometry;
    settings.outformat = "pdf";
    unitsize(1.5cm);

    picture realpane;
    unitsize(realpane,1.5cm);

    real x = 4.0, y = 3.0;
    real a = 1.0, b = 3.0, c = 1.0, d = 2.0;

    // Axes
    label(realpane, "$O$", (0,0), align=SW);
    draw(realpane, (-0.5,0) -- (x,0), L=Label("$x$", align=S, position=EndPoint));
    draw(realpane, (0,-0.5) -- (0,y), L=Label("$y$", align=W, position=EndPoint));

    // Ticks
    draw(realpane, (a,0) -- (a,-0.1), L=Label("$a$",align=S));
    draw(realpane, (b,0) -- (b,-0.1), L=Label("$b$",align=S));
    draw(realpane, (0,c) -- (-0.1,c), L=Label("$c$",align=W));
    draw(realpane, (0,d) -- (-0.1,d), L=Label("$d$",align=W));

    // Square
    draw(realpane, box((a,c),(b,d)), p=linewidth(2));
    label(realpane, "$A$", (a,c), align=SW);
    label(realpane, "$B$", (b,c), align=SE);
    label(realpane, "$C$", (b,d), align=NE);
    label(realpane, "$D$", (a,d), align=NW);
    draw(realpane, (a+0.5,c) -- (a+0.5,d), arrow=MidArrow());

    picture complexpane;
    unitsize(complexpane,1.5cm);

    pair A = 1.5*dir(30), B = 3*dir(30), C = 3*dir(70), D = 1.5*dir(70);

    // Axes
    label(complexpane, "$O$", (0,0), align=SW);
    draw(complexpane, (-0.5,0) -- (x,0), L=Label("$u$", align=S, position=EndPoint));
    draw(complexpane, (0,-0.5) -- (0,y), L=Label("$v$", align=W, position=EndPoint));

    // Help Lines
    draw(complexpane, (0,0) -- B);
    draw(complexpane, (0,0) -- C);

    // Angles
    draw(complexpane, arc((x,0),(0,0),D,0.6), L=Label("$\phi = d$", align=NE, position=EndPoint), arrow=Arrow());
    draw(complexpane, arc((x,0),(0,0),A,0.8), L=Label("$\phi = c$", align=E, position=MidPoint), arrow=Arrow());

    // Transformation
    draw(complexpane, A -- B -- arc(B,(0,0),C,3) -- C -- D -- arc(D,(0,0),A,1.5), p=linewidth(2));
    label(complexpane, "$A'$", A, align=E);
    label(complexpane, "$B'$", B, align=SE);
    label(complexpane, "$C'$", C, align=NE);
    label(complexpane, "$D'$", D, align=NW);
    draw(complexpane, arc(B,(0,0),C,1.9), arrow=MidArrow());

    add(realpane.fit(),(0,0),W);
    add(complexpane.fit(),(0,0),E);
\end{asy}
\end{document}

введите описание изображения здесь


Исправленный код асимптоты

Благодаря комментариям Чарльза Стаатса мне удалось улучшить код и избавиться от лишнего picture.

\documentclass{standalone}
\usepackage[inline]{asymptote}
\begin{document}
\begin{asy}
    import geometry;
    settings.outformat = "pdf";
    unitsize(1.5cm);
    pen thick = linewidth(1.6pt);

    real x = 4.0, y = 3.0;
    real a = 1.0, b = 3.0, c = 1.0, d = 2.0;

    // Axes
    label("$O$", (0,0), align=SW);
    draw((-0.5,0) -- (x,0), L=Label("$x$", align=S, position=EndPoint));
    draw((0,-0.5) -- (0,y), L=Label("$y$", align=W, position=EndPoint));

    // Ticks
    draw((a,0) -- (a,-0.1), L=Label("$a$",align=S));
    draw((b,0) -- (b,-0.1), L=Label("$b$",align=S));
    draw((0,c) -- (-0.1,c), L=Label("$c$",align=W));
    draw((0,d) -- (-0.1,d), L=Label("$d$",align=W));

    // Square
    draw(box((a,c),(b,d)), p=thick);
    label("$A$", (a,c), align=SW);
    label("$B$", (b,c), align=SE);
    label("$C$", (b,d), align=NE);
    label("$D$", (a,d), align=NW);
    draw((a+0.5,c) -- (a+0.5,d), arrow=MidArrow());

    currentpicture = shift(-6,0)*currentpicture;

    pair A = 1.5*dir(30), B = 3*dir(30), C = 3*dir(70), D = 1.5*dir(70);

    // Axes
    label("$O$", (0,0), align=SW);
    draw((-0.5,0) -- (x,0), L=Label("$u$", align=S, position=EndPoint));
    draw((0,-0.5) -- (0,y), L=Label("$v$", align=W, position=EndPoint));

    // Help Lines
    draw((0,0) -- B);
    draw((0,0) -- C);

    // Angles
    draw(arc((x,0),(0,0),D,0.6), L=Label("$\phi = d$", align=N+1.5E, position=EndPoint), arrow=ArcArrow());
    draw(arc((x,0),(0,0),A,0.8), L=Label("$\phi = c$", align=E, position=MidPoint), arrow=ArcArrow());

    // Transformation
    draw(A -- B -- arc(B,(0,0),C,3) -- C -- D -- arc(D,(0,0),A,1.5), p=thick);
    label("$A'$", A, align=SE);
    label("$B'$", B, align=SE);
    label("$C'$", C, align=NE);
    label("$D'$", D, align=NW);
    draw(arc(B,(0,0),C,1.9), arrow=MidArcArrow());

    add(realpane.fit(),(0,0),W);
    add(complexpane.fit(),(0,0),E);
\end{asy}
\end{document}

введите описание изображения здесь

решение4

Асимптота против Мудреца

Я отправляю пример, созданный в Asymptote, который работает и не работает (баг?), надеюсь, это никого не обидит. У меня была возможность сравнить Asymptote и Sage (на этот раз не TikZ и не PSTricks, извините), в любом случае я хотел бы поделиться своим скромным опытом.

История

Но перед этим, если вы так любезно просите, я расскажу вам историю за кулисами создания этих картин. За нашей работой всегда стоит история.

Однажды я встретил девушку. Виртуально, конечно, как же еще? И я хотел произвести впечатление на этого математика. Поэтому мне дали задание (ее школьное домашнее задание) решить три из ее трех задач, прежде чем я получу шанс встретиться с ней лицом к лицу. Задачи по математике, что-то с интегралами для вычисления... Я решил заняться интерактивной математикой, я был так взволнован всем этим, что параллельно решал те же задачи в двух программах. В Sage (Python с поддержкой Jmol) и в Asymptote (PDF).

Я сделал все, что мог, и вы увидите результаты через минуту. Но была одна загвоздка! Мои результаты были не совсем идеальными. В то время блокнот Sage не был общедоступным, и я не смог убедить Jmol экспортировать мне 3D-модель в PDF.

А как насчет Asymptote? Даже Asymptote не спас день. Если вы попробуете мой пример и раскомментируете ifусловие (строки 25 и 32), вы получите ошибку no matching variable 'f'(даже Linux и Microsoft Windows согласились с этим). Если вы попытаетесь спасти день, раскомментировав строку 20 в дополнение к этому, вы получите самолет!

Как только она это увидела, она тут же меня бросила, да и как еще?

Оглядываясь назад, я думаю, что она не была математиком, но она была TeXистом! Бедняжка!

Обратно в реальность

Sage предоставил мне очень хороший интерфейс. Он был интерактивным, уравнения были набраны в TeX, он вычислял площади, объемы, а модели были в 3D (Jmol основан на Java). Asymptote предоставил мне идеальное решение, чтобы сделать эти 3D-модели интерактивными и в PDF-файле.

(Инкапсулированный) постскриптум

Пожалуйста, ознакомьтесь с разделом комментариев, чтобы заставить этот mal-asymptote.asyфайл работать так, как он должен работать!

import settings;
outformat="eps";
// settings.render=16;
// interactiveView=false;
// batchView=false;

// User's preference...
// pick up a function: none, 1st, 2nd or 3rd
// write(whichcurve==3); // inform me in the terminal
real whichcurve=1; // 0, 1, 2 or 3 

// The core of the program...
import graph3;
import solids;
size(300);
currentlight=Viewport; // no light;
pen colora=green;
pen colorb=blue;

//real f(real x) {return 0;} // :-) // line 20
real mallower;
real malupper;
string maldesc;

//if (whichcurve == 1) { // line 25
  currentprojection=perspective(2,2,4,up=Y);
  write("Creating first function...");
  real f(real x) {return sqrt(3+x);} // line 28
  maldesc="$\sqrt{3+x}$";
  mallower=-1;
  malupper=3;
//  } // == 1 // line 32

if (whichcurve == 2) {
  currentprojection=perspective(0,2,2,up=Y);
  write("Creating second function...");
  real f(real x) {return sqrt((x-2)/(2x+1));} // line 37
  maldesc="$\sqrt{\frac{x-2}{2x+1}}$";
  mallower=2;
  malupper=3;
  } // == 2

if (whichcurve == 3) {
  currentprojection=perspective(0,-0.5,2,up=Y);
  write("Creating third function...");
  real f(real x) {return sqrt((2-x)/(3+2x));} // line 46
  maldesc="$\sqrt{\frac{2-x}{3+2x}}$";
  mallower=1;
  malupper=2;
  } // == 3

pair F(real x) {return (x,f(x));}
triple F3(real x) {return (x,f(x),0);}

path p=graph(F,mallower,malupper,n=10,operator ..);
path3 p3=path3(p);
//triple pO=(0,0,0);

render render=render(merge=true);
revolution a=revolution(p3,X,140,360);
draw(surface(a),colora,render);
revolution b=revolution(p3,Y,0,220);
draw(surface(b),colorb,render);

real xmax=malupper+0.4;
real ymax=max(abs(f(mallower)),abs(f(malupper)))+0.2;
draw(Label("$x$",xmax,E),(0,0,0)--(xmax,0,0),Arrow3);
draw((0,0,0)--(-xmax,0,0),dashed);
draw(Label("$y(x)=$"+maldesc,ymax,N),(0,0,0)--(0,ymax,0),Arrow3);
draw((0,0,0)--(0,-ymax,0),dashed);
//draw(Label(maldesc,ymax),(0,ymax,0)--(xmax,ymax,0));
//draw((0,0,0)--(0,0,f(malupper)),Arrow3);

мвэ, асимптота

мве, шалфей

Связанный контент