36

Problem

This is a shameless "just do it for me" graphics question, but honestly I have no idea where to start. I'd like to reproduce this figure

enter image description here

The image shows the intersection of two surfaces of constant gibbs energy.

What I have tried so far

Well, I didn't really try something, but here is a template to save you time.

\documentclass[tikz]{standalone}
\usepackage{tikz-3dplot}
\begin{document}
\tdplotsetmaincoords{70}{110}
\begin{tikzpicture}[tdplot_main_coords]
    \draw[->] (0,0,0) -- (4,0,0) node[below] {$p$};
    \draw[->] (0,0,0) -- (0,4,0) node[below] {$T$};
    \draw[->] (0,0,0) -- (0,0,4) node[left] {$\mu$};
\end{tikzpicture}
\end{document}

Additional stuff

  • I'd like to have a TikZ answer.
  • Usage of tikz-3dplot is not required.
  • Feel free to downvote or vote for closing this question, as it is a shameless "just do it for me" question.
  • I'm bad and I should feel bad!

Related:

  • I'm confused by the terminology. Are we talking about planes in particular, or surfaces in general? – jub0bs Feb 6 '14 at 21:41
  • @Jubobs My english is not that good. Is there a difference? – Henri Menke Feb 6 '14 at 22:25
  • 2
    A plane is flat, and is usually drawn as a parallelogram. A surface could be a plane, sphere, hyperboloid,.... Planes are usually much easier to draw than other surfaces. – Charles Staats Feb 6 '14 at 23:42
  • @Charles Staats Then I mean surfaces :-) Thank you for improving my question. I edited it accordingly. – Henri Menke Feb 7 '14 at 7:34
  • TikZ can't figure out on its own which part of each surface is behind the other surface (or behind another part of itself). I use Asymptote for these kind of problems; it takes about 2 hours to learn. – Benjamin McKay Feb 7 '14 at 8:18
36
+100

One option using TikZ:

enter image description here

The code:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{intersections}

\begin{document}

\begin{tikzpicture}[xscale=0.8,>=latex]
% axis
\draw[ultra thick,->] (0.3,-3.5) -- +(0,7) node[yshift=5pt] {$\mu$};
\draw[ultra thick,->] (0.3,-3.5) -- +(220:4) node[yshift=-5pt,xshift=-5pt] {$p$};
\draw[ultra thick,->] (0.3,-3.5) -- +(12,0) node[xshift=6pt] {$T$};

% border of the surface1
\path[draw,name path=border1] (0,0) to[out=-10,in=150] (6,-2);
% border of the surface1
\path[draw,name path=border2] (12,1) to[out=150,in=-10] (5.5,3.2);
% border of the surface1
\draw[draw,thick,name path=line1] (6,-2) -- (12,1);
% border of the surface1
\path[draw,name path=line2] (5.5,3.7) -- (0,0);
% draw the surface1
\shade[left color=gray!10,right color=gray!70] 
  (0,0) to[out=-10,in=150] (6,-2) -- 
  (12,1) to[out=150,in=-10] (5.5,3.7) -- cycle;

% border of the surface2
\path[draw,name path=border3] (-1,-4) to[out=20,in=220] (3,3);
% border of the surface2
\path[draw,name path=border4] (6,-7) to[out=40,in=210] (9,1);
% border of the surface2
\path[draw,name path=border5] (-1,-4) to[out=0,in=80] (6,-7);
% border of the surface2
\path[draw,name path=border6] (3,3) to[out=10,in=140] (9,1);

% labels
\node at (0.5,-3.8) {$\alpha$};
\node at (10,1) {$\beta$};
\node at (9.4,-4.5) (label) {$p_{\alpha\beta}(T)$};
\draw[->] (label) -- +(185:3.35);

% draw the surface2
\shade[top color=gray!10,bottom color=gray!90,opacity=.30] 
  (-1,-4) to[out=20,in=220] (3,3)  to[out=10,in=140] (9,1)
 to[out=210,in=40] (6,-7) to[out=80,in=0] (-1,-4);

% intersection points
\path[name intersections={of=border3 and line2,by={a}}];
\path[name intersections={of=border4 and line1,by={b}}];

% intersection of the surfaces
\draw[thick,dashed] (a) to[out=-10,in=130] (b);

% proyections of the intersection points
\draw[help lines,gray!70] (a) -- +(0,-4.9) coordinate (proy1);
\draw (b) -- +(0,-5) coordinate (proy2);

% proyection of the intersection path
\draw[ultra thick] (proy1) to[out=0,in=130] (proy2);

\end{tikzpicture}

\end{document}
  • This is great work. Just needed to make such a graphic, and here is something similar. – Guido Jorg Sep 30 '14 at 23:52
20

Using Asymptote. The surface $\beta$ has an element of randomness to it; to see other possibilities, change the integer in the srand(int); command. The routine to compute the intersection of the two Bezier patches is one I designed for this scenario; it will not work more generally.

enter image description here

Here's the Asymptote code:

settings.outformat="png";
settings.render=16;

import three;
size(10cm);

defaultpen(fontsize(10pt) + linewidth(0.4pt));
usepackage("lmodern");

//currentprojection=orthographic(5,2,3);
currentprojection=obliqueX;

draw(O -- 3X, arrow=Arrow3(HookHead2(normal=Y+Z),emissive(black)), L=Label("$p$",position=EndPoint,align=2E));
draw(O -- 3Y, arrow=Arrow3(HookHead2,emissive(black)), L=Label("$T$",position=EndPoint,align=2S));
draw(O -- 1.5Z, arrow=Arrow3(HookHead2,emissive(black)), L=Label("$\mu$",position=EndPoint,align=2SW));

transform3 T = shift(-Y)*rotate(angle=45, 2Y, 2Y+Z);


//path3 lineOutline = (0,0,0) -- (0,2,1) -- (2,2,1) -- (2,0,0) -- cycle;
triple normal1 = T*unit(cross((2,2,1),(0,2,1)));

path3 outline1 = O {Y+.1Z} .. {Y+.3Z} (0,2,1) {X+.5Y} .. {X-.5Y} (2,2,1) {-Y-.3Z} .. {-Y-.1Z} (2,0,0) {-X+1.0Y} .. {-X-1.0Y} cycle;
outline1 = T*outline1;
surface s1 = surface(patch(outline1));
draw(shift(-5*currentprojection.camera)*s1, surfacepen=material(lightgray,ambientpen=white));
draw(outline1);

path3 lineoutline2 = T*plane(O=(0,1.2,0.8), 2X, 1.7Y);
triple normal2 = Z;

srand(0);
triple[][] controlpoints = copy(patch(lineoutline2).P);
for (int i = 0; i < 4; ++i) {
  for (int j = 0; j < 4; ++j) {
    if (i % 3 == 0)
      controlpoints[i][j] += 0.3*(0,0,unitrand()-.5);
    else
      controlpoints[i][j] += 0.3*((unitrand(), unitrand(), unitrand()) - (.5,.5,.5));
  }
}

patch s2patch = patch(controlpoints);
surface s2 = surface(s2patch);
draw(shift(-5*currentprojection.camera)*s2, surfacepen=material(white,ambientpen=white,emissivepen=darkgray));
draw(s2patch.external());

triple[] isectionEndpoints = intersectionpoints(outline1, s2patch.external());
triple p = isectionEndpoints[0];
triple q = isectionEndpoints[1];

int nPoints = 10;
int nIter = 20;

triple toS1(triple start) {
  path3 segment = start-normal1 -- start+normal1;
  return intersectionpoints(segment, s1)[0];
}
triple toS2(triple start) {
  path3 segment = start+normal2 -- start-normal2;
  return intersectionpoints(segment, s2)[0];
}

triple toIntersection(triple start) {
  for (int i = 0; i < nIter; ++i) {
    start = toS1(start);
    start = toS2(start);
  }
  return start;
}

triple[] isectionPoints;
isectionPoints.push(p);
for (int i = 1; i < nPoints; ++i) {
  isectionPoints.push(toIntersection(interp(p, q, i/nPoints)));
}
isectionPoints.push(q);
path3 isectionpath = operator..(...isectionPoints);
draw(isectionpath, dashed+linewidth(0.7pt));

path3 projectedIsection = planeproject(plane(X,Y)) * isectionpath;

path3 extension(path3 g, real extensionlength) {
  triple startextend = extensionlength * unit(dir(g,0));
  triple endextend = extensionlength * unit(dir(g, length(g)));
  return beginpoint(g)-startextend -- g -- endpoint(g) + endextend;
}

draw(extension(projectedIsection, 0.3), linewidth(0.8pt), margin=Margin3(-4,-4));
draw(beginpoint(isectionpath) -- beginpoint(projectedIsection) ^^ endpoint(projectedIsection) -- endpoint(isectionpath));

triple pointat = relpoint(projectedIsection,0.6);
draw(pointat .. controls pointat+Y and pointat+.4X .. pointat+Y+.4X, p=linewidth(0.2pt), arrow=BeginArrow3(HookHead2,emissive(black)), L=Label("$p_{\alpha\beta}(T)$",position=EndPoint));

label("$\alpha$", s1.point(.1,.6), align=NE);
label("$\beta$", s2.point(.5,.85));

To compile the image, save the code in filename.asy and then run asy filename.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.