# 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

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}


• 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.

Related:

• I'm confused by the terminology. Are we talking about planes in particular, or surfaces in general? Feb 6, 2014 at 21:41
• @Jubobs My english is not that good. Is there a difference? Feb 6, 2014 at 22:25
• 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. Feb 6, 2014 at 23:42
• @Charles Staats Then I mean surfaces :-) Thank you for improving my question. I edited it accordingly. Feb 7, 2014 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. Feb 7, 2014 at 8:18

One option using TikZ:

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
(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
(-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. Sep 30, 2014 at 23:52

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.

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.