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
.
:-)
Thank you for improving my question. I edited it accordingly.