38

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:

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

2 Answers 2

40
+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}
1
  • This is great work. Just needed to make such a graphic, and here is something similar. Commented Sep 30, 2014 at 23:52
23

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.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .