在 Tikz 中绘制黑洞

在 Tikz 中绘制黑洞

我需要在 tikz 中绘制类似下面两张图片的内容:

在此处输入图片描述在此处输入图片描述

这在《万有引力》(MTW)一书中的图 34.8 中有所启发。

在此处输入图片描述

谁能告诉我如何画这些图吗?

答案1

我不了解 Tikz,但这里有一个 MetaPost/MetaFun 入门教程,也许可以帮你入门。编译自context。玩得开心!

一张黑洞的照片(天哪!)

\starttext
\startMPpage[offset=3bp,instance=doublefun]
u:=1cm;% overall unit

% (theta,phi) spherical coordinates for viewpoint direction
theta:=-80;
phi:=15;

% scalar product
primarydef u cdotprod v =
    redpart u*redpart v + greenpart u*greenpart v + bluepart u*bluepart v
enddef;

% Projection from 3D to 2D
vardef P primary x =
    save ct,st,sp;
    ct:=cosd(theta);
    st:=sind(theta);
    sp:=sind(phi);
    (x cdotprod (-st,ct,0),x cdotprod (-ct*sp,-st*sp,cosd(phi)))
enddef;


path S[],seam[],torso,waist,knee[],innerpants,outerpants[],grays[];
pair toe[],scrotch;

% The planes
S[1] = (P(-3.5,-2.5,0)
       --
       P(2,-2.5,0)
       --
       P(2,2.5,0)
       --
       P(-3.5,2.5,0)
       --
       cycle) 
       randomizedcontrols 0.75 scaled u;

S[2] = (P(-3.5,-2.5,3)
       --
       P(2,-2.5,3)
       --
       P(2,2.5,3)
       --
       P(-3.5,2.5,3)
       --
       cycle)
       randomizedcontrols 0.75 scaled u;

% The body
torso = (P(1,0,6)
        ...
        P(0,1,6)
        ...
        P(-1,0,6)
        ...
        P(0,-1,6)
        ...
        cycle)
        randomizedcontrols 0.2 scaled u;


waist = (P(1,0,3)
        ...
        P(0,1,3)
        ...
        P(-1,0,3)
        ...
        P(0,-1,3)
        ...
        cycle) 
        randomizedcontrols 0.2 scaled u;

knee[1] = (P(1,0,0)
          ...
          P(0.75,0.4,0)
          ...
          P(0.5,0,0)
          ...
          P(0.75,-0.4,0)
          ...
          cycle)
          randomized 0.0 scaled u;

knee[2] = (P(-0.5,0,0)
          ...
          P(-0.75,0.4,0)
          ...
          P(-1,0,0)
          ...
          P(-0.75,-0.4,0)
          ...
          cycle) 
          randomized 0.0 scaled u;

toe[1] = P(0.8,-0.3,-2.3) scaled u;

toe[2] = P(-0.9,0,-1.8) scaled u;

scrotch = P(0,0,1.5) scaled u; 

outerpants[1] = (directionpoint dir 80 of torso){dir -100} 
                .. 
                {down}(directionpoint up of waist)
                ..
                (directionpoint up of knee[1])
                ..
                toe[1];

outerpants[2] = (directionpoint dir -80 of torso){dir -80}
                ..
                {down}(directionpoint down of waist)
                ..
                (directionpoint down of knee[2])
                ..
                {dir -80}toe[2];

innerpants = (toe[1]
             ..
             (directionpoint down of knee[1])
             ..
             {dir 115}scrotch{dir -105}
             ..
             (directionpoint up of knee[2])
             ..
             {dir -105}toe[2]);

for i=1 upto 5:
   seam[i] = (point 2.3+0.08i of torso){dir -87}
             ..
             (point 2.2+0.075i of waist)
             ..
             (point 2.35+0.2i of knee[2])
             ..
             toe[2];
endfor;


for i=6 upto 10:
    seam[i] = (point 2.8+0.06i of torso){dir -90}
              ..
              (point 2.7+0.065i of waist)
              ..
              {dir -90}(point 2.3-0.1(i-5) of innerpants);
endfor;

grays[1] = subpath(xpart(reverse outerpants[1] intersectiontimes waist),
                   xpart(reverse outerpants[1] intersectiontimes torso)) 
                   of reverse outerpants[1]
           -- 
           subpath(xpart(torso intersectiontimes outerpants[1]),
                   xpart(torso intersectiontimes outerpants[2]))
                   of torso
           --
           subpath(xpart(outerpants[2] intersectiontimes torso),
                   xpart(outerpants[2] intersectiontimes waist))
                   of outerpants[2]
           --
           subpath(xpart(reverse waist intersectiontimes outerpants[2]),
                   xpart(reverse waist intersectiontimes outerpants[1]))
                   of reverse waist
           -- 
           cycle;


grays[2] = subpath(xpart(outerpants[1] intersectiontimes knee[1]),
                   xpart(outerpants[1] intersectiontimes subpath(0,1) of S[2]))
                   of outerpants[1]
           -- 
           reverse subpath(xpart(S[2] intersectiontimes reverse outerpants[1]),
                           xpart(S[2] intersectiontimes reverse outerpants[2]))
                           of S[2]
            --
            subpath(xpart(outerpants[2] intersectiontimes (subpath(0,1) of S[2])),       xpart(outerpants[2] intersectiontimes knee[2])) 
                    of outerpants[2] 
            --
            subpath(xpart(knee[2] intersectiontimes outerpants[2]),
                    xpart(knee[2] intersectiontimes innerpants))
                    of knee[2]
            --
            subpath(xpart(reverse innerpants intersectiontimes knee[2]),
                    xpart(reverse innerpants intersectiontimes knee[1]))
                    of reverse innerpants
            --
            subpath(xpart(knee[1] intersectiontimes innerpants),
                   xpart(knee[1] intersectiontimes outerpants[1]))
                   of knee[1]
            -- 
            cycle;

grays[3] = subpath(0,
                   xpart(reverse outerpants[1] intersectiontimes S[1]))
                   of reverse outerpants[1]
            --
            reverse subpath(xpart(S[1] intersectiontimes reverse subpath(0,1) of innerpants),
                            xpart(S[1] intersectiontimes reverse outerpants[1]))
                            of S[1]
            --
            reverse subpath(0,
                            xpart(innerpants intersectiontimes S[1]))
                            of innerpants
            -- 
            cycle;

grays[4] = subpath(0,
                   xpart(reverse innerpants intersectiontimes S[1]))
                   of reverse innerpants
            --
            reverse subpath(xpart (S[1] intersectiontimes reverse outerpants[2]),               xpart (S[1] intersectiontimes reverse innerpants)) 
                            of S[1] 
            --
            reverse subpath(0, 
                            xpart (reverse outerpants[2] intersectiontimes S[1])) of (reverse outerpants[2])
            -- 
            cycle;


% Drawing time

% The planes
draw S[1]; 
draw S[2];

% Fill
for i = 1 upto 4:
    fill grays[i] withcolor 0.75white;
endfor;

draw grays[3];
draw grays[4];

% Fix parts that were filled
draw subpath(xpart (S[2] intersectiontimes reverse outerpants[2]),
             xpart (S[2] intersectiontimes reverse outerpants[1])) 
             of S[2];

draw subpath(xpart (S[1] intersectiontimes reverse outerpants[2]),
             xpart (S[1] intersectiontimes reverse innerpants)) 
             of S[1];

draw subpath(xpart (S[1] intersectiontimes innerpants),
             xpart (S[1] intersectiontimes reverse outerpants[1])) 
             of S[1];

% Draw the rest of the parts
draw torso;

draw subpath(0,
             xpart(outerpants[1] intersectiontimes waist))
             of outerpants[1];

draw subpath(xpart(reverse outerpants[1] intersectiontimes knee[1]),
             xpart(reverse outerpants[1] intersectiontimes S[2])) 
             of reverse outerpants[1];

draw subpath(0,
             xpart(reverse outerpants[1] intersectiontimes S[1]))
             of reverse outerpants[1];

draw subpath(0,
             xpart(innerpants intersectiontimes S[1]))
             of innerpants;


draw subpath(xpart(innerpants intersectiontimes knee[1]),
             xpart(innerpants intersectiontimes knee[2]))
             of innerpants;

draw subpath(xpart(outerpants[2] intersectiontimes torso),
             xpart(outerpants[2] intersectiontimes waist))
             of outerpants[2];

draw subpath(xpart(reverse outerpants[2] intersectiontimes knee[2]),
             xpart(reverse outerpants[2] intersectiontimes S[2])) 
             of reverse outerpants[2];

for i=1 upto 10:
  draw subpath(0,
               xpart(seam[i] intersectiontimes reverse waist)) 
               of seam[i];
endfor;

for i=1 upto 5:
  draw subpath(xpart(reverse seam[i] intersectiontimes reverse knee[2]),
               xpart(reverse seam[i] intersectiontimes S[2])) 
               of reverse seam[i];
  draw subpath(0,
               xpart(reverse seam[i] intersectiontimes S[1])) 
               of reverse seam[i];
endfor;

for i=6 upto 10:
   draw subpath(0,
                xpart(reverse seam[i] intersectiontimes S[2])) 
                of reverse seam[i];
endfor;

\stopMPpage
\stoptext

相关内容