在 Asymptote 中绘制圆环楔形

在 Asymptote 中绘制圆环楔形

有人知道如何用渐近线在圆环上画一个小楔子吗?

这是我目前所拥有的,但我希望能够以某种方式为我的楔形立方体添加阴影。然而,目前我的立方体由许多部分组成,所以我真的不知道该怎么做。

这是我目前的代码。你会注意到,它的第一部分(实际上看起来不错的部分!)是相当厚颜无耻地直接从第二个答案中摘录的这里。我更喜欢将代码放在 Asymptote 中,而不是 tikz 中,但我很灵活。

另外,我不太关心如何楔形看起来,所以如果将其做成圆锥形或稍微不同的长方体(甚至以圆环上的不同点为中心)更方便,我也可以接受。唯一的问题是我希望楔形在某个地方结束里面圆环,也就是说,我不想要圆环。

非常感谢!

settings.outformat = "pdf"; 
settings.prc = false; 
settings.render = 0; 

import graph3; 
size3(12cm);

currentprojection = orthographic(10,1,4);
defaultrender = render(merge = true);

int umax, vmax; 
umax = 40; 
vmax = 40; 

surface torus = surface(Circle(c=2Y, r=0.6, normal=X, n=vmax), c=O, axis=Z, n=umax);
torus.ucyclic(true);
torus.vcyclic(true);

pen meshpen = 0.3pt+black;

draw(torus, surfacepen=material(diffusepen=blue+opacity(0.3), emissivepen=white));
for (int u = 0; u < umax; ++u) {
    real op; 
    if (u <= 0 || u >= umax/2.0) {
        op = 0.5; 
    } else {
        if (u == 1 || u >= umax/2.0-1) {
            op = 0.35; 
        } else {
            op = 0.2; 
        } 
    } 
    draw(torus.uequals(u), p=meshpen+opacity(op));
}
for (int v = 0; v < vmax; ++v) {
    draw(graph(new triple(real u) {return torus.point(u,v); }, 0, umax, operator ..),p=meshpen+opacity(0.2));
}

int pos = floor(3*umax/4)-2;
pair p = (pos, 3);
dot(torus.point(p.x, p.y));

path3 toruspath(pair pt1, pair pt2, int ucycles, int vcycles) {
  pair pt2shift = (ucycles*umax, vcycles*vmax);
  triple f(real t) {
    pair uv = (1-t)*pt1 + t*(pt2+pt2shift);
    return torus.point(uv.x, uv.y);
  }
  return graph(f, 0, 1, operator ..);
}

triple scaletriple(triple t, real scalefactor) {
    return (scalefactor*t.x,scalefactor*t.y,scalefactor*t.z); 
} 

path3 scalepath(path3 initpath, real scalefactor) {
    triple f(real t) {
        return scaletriple(arcpoint(initpath,t),scalefactor); 
    } 
    return graph(f, 0, 1, operator ..); 
} 

pair w,x,y,z; 
w = (pos-0.5,1); 
x = (pos+0.5,1); 
y = (pos+0.5,5); 
z = (pos-0.5,5); 
// draw(torus.point(w.x,w.y)--torus.point(x.x,x.y)--torus.point(y.x,y.y)--torus.point(z.x,z.y)--cycle); 

path3 sides[] = {toruspath(w,x,0,0), toruspath(x,y,0,0), toruspath(y,z,0,0), toruspath(z,w,0,0)};

for (path3 side : sides) {
    draw(side); 
    draw(scalepath(side,0.9),black+opacity(0.5)); 
} 

pair points[] = {w,x,y,z}; 
for (pair pt : points) {
draw(torus.point(pt.x,pt.y)--scaletriple(torus.point(pt.x,pt.y),0.9),black+opacity(0.75));
}

圆环楔

答案1

既然你说“我很灵活”,我使用 TikZ 绘制圆环和其中的小“立方体”,其中一个面位于圆环上。我认为这个面的顶点一定是圆环绘制过程中出现的点。因此,圆环是使用四边形网格绘制的。网格的点是从经典参数化构造的。

以下是代码的一些说明。前两项是经典且众所周知的。请注意,我们需要 3D 点和向量的三个分量来进行各种计算。由于我们无法从 TikZ 中恢复它们协调定义,它们被计算(太)多次;代码可以改进。

  1. 观察者的视点由单位向量定义指向观察者。其组成部分包括\毒素\玩具, 和\托兹, 在哪里
    \tox = x_= 正弦\经度 余弦\纬度
    \玩具= y_= 正弦\纬度
    \toz = z_= 余弦\经度 余弦\纬度.
    角度\长\纬度分别代表经度和纬度。
  1. 屏幕(绘制图像的平面)是通过原点并正交于. 诱导屏幕坐标系的正交基是, 在哪里
    = ( 余弦, 0 , - 正弦)
    = (- 正弦\经度 正弦\纬度, 余弦\纬度, - 余弦\经度 正弦\纬度)

注意初始坐标系是,这样当\经度=\纬度=0盎司是水平的,被观察者视为一个点,并且是水平的,并且指向观察者的右侧。因此,平行于奥克斯; 尤其\纬度必须与直角不同。

要点(1,0,0)(0,1,0), 和(0,0,1)投影到绘图的全局选项中描述的点上x={(\newxx 厘米, \newxy 厘米)}等,例如,\newxx = <(1,0,0),>, \newxy = <(1,0,0),>

我一直在思考这些问题,因为绘制 3D 物体取决于观察者的位置向量,

  1. 我们将圆环视为围绕奥伊半径为圆的轴\rz在飞机上. 圆心到奥伊\ry。因此,我们的网格由点定义(P-\j-\k);作为 3D 点,它们的坐标与往常一样(参见代码)。我只想指出-坐标有一个减号,
    -\rz sin(360(\k/\Nz)), 和0<=\k<=\Nz
    之所以存在,是因为经度周期上的四边形应视为顺时针方向(从 3 点开始)。这种选择是正确的,当属于第一象限。

为了\j固定的,这些点描述一个经度周期(半径为\rz); 为了\k固定的点描述了一个纬度周期。特别是,最长的纬度周期(圆环与圆心的交点)奥兹克平面)获得\k=0

  1. 绘制的网格四边形由以下函数给出已看到返回1如果对应于位置向量的内积(P-\j-\k)是正数。
\documentclass[margin=10pt]{standalone}
\usepackage{ifthen}
\usepackage[rgb]{xcolor}
\usepackage{tikz}
\usetikzlibrary{cd, arrows, matrix, intersections, math, calc}

\begin{document}
\tikzmath{%
  real \ry, \rz, \longit, \latit, \tox, \toy, \toz;
  real \newxx, \newxy, \newyx, \newyy, \newzx, \newzy;  
  integer \Ny, \Nz, \prevj, \prevk;
  % \j moves around Oy and \k moves around Oz.
  % They must describe full circles of radii \ry and \rz respectively.
  \ry = 4;
  \rz = 1.5;
  \longit = 24;
  \latit = 35;
  \tox = sin(\longit)*cos(\latit);
  \toy = sin(\latit);
  \toz = cos(\longit)*cos(\latit);
  \newxx = cos(\longit); \newxy = -sin(\longit)*sin(\latit);
  \newyy = cos(\latit);
  \newzx = -sin(\longit); \newzy = -cos(\longit)*sin(\latit);
  \Nz = 36;
  \Ny = 84;
  \ktmp = \Nz-1; 
  \jtmp = \Ny-1;
  function isSeen(\j, \k) {
    let \px = cos(360*(\k/\Nz))*cos(360*(\j/\Ny));
    let \py = -sin(360*(\k/\Nz));
    let \pz = cos(360*(\k/\Nz))*sin(360*(\j/\Ny));
    let \res = \px*\tox + \py*\toy + \pz*\toz;
    if \res>0 then {return 1;} else {return 0;};
  };
}
\begin{tikzpicture}[every node/.style={scale=.8},
  x={(\newxx cm, \newxy cm)},
  y={(0 cm, \newyy cm)},
  z={(\newzx cm, \newzy cm)},
  evaluate={%
    int \j, \k;
    for \j in {0, 1, ..., \Ny}{%   \Ny = 84
      for \k in {0, 1, ..., \Nz}{%  \Nz = 36
        \test{\j,\k} = isSeen(\j, \k);
      };
    };
  }]

  % coordinate system $Oxyz$; first layer
  % must be drawn in two steps (there are 2 objects in the final figure)
  \draw[green!50!black]
  (0, 0, 0) -- (\ry, 0, 0)
  % (0, 0, 0) -- (0, \ry+\rz, 0)
  (0, 0, 0) -- (0, 0, \ry);

  % points (P-\j-\k)
  % The minus sign for the y component is due to the fact that
  % the points (for a vertical circle) are to be considered 
  % clockwise starting with 3 o'clock.  Of course, it depends on the
  % observer's position, but in case this position is in the first
  % quadrant, this is the good order.
  \foreach \j in {0, ..., \Ny}{%
    \foreach \k in {0, ..., \Nz}{%
      \path
      ( {( \ry+\rz*cos(360*(\k/\Nz)) )*cos(360*(\j/\Ny))},
      {-\rz*sin(360*(\k/\Nz))},
      {( \ry+\rz*cos(360*(\k/\Nz)) )*sin(360*(\j/\Ny))} )
      coordinate (P-\j-\k);
    }
  }

  % "squares"---the mesh
  % first j then k; in this way the upper "latitude bands" are drawn
  % at the end and the torus appears correctly.
  \foreach \k [remember=\k as \prevk (initially 0)] in {1, ..., \Nz}{%
    \foreach \j [remember=\j as \prevj (initially 0)] in {1, ..., \Ny}{%
      \ifthenelse{\test{\j,\k}=1}{
        \draw[blue!50, very thin, fill=blue!15]
        (P-\j-\prevk) -- (P-\prevj-\prevk)
        -- (P-\prevj-\k) --(P-\j-\k) -- cycle;
      }{}
    }
  }

  % cube inside the torus with one face on the torus defined by
  % latitude and longitude cycles
  \begin{scope}[evaluate={%
      for \j in {0, 1, 2}{ \a{\j} = int(\Ny/4+3+\j); };
      for \k in {0, 1, 2, 3}{ \b{\k} = int(\Nz-3+\k); };
    }]
    % face of the "cube"
    \filldraw[blue!25] (P-\a{0}-\b{0})
    \foreach \k in {1, 2, 3}{-- (P-\a{0}-\b{\k})}
    -- (P-\a{1}-\b{3}) -- (P-\a{2}-\b{3})
    \foreach \k in {2, 1, 0}{-- (P-\a{2}-\b{\k})}
    -- (P-\a{1}-\b{0}) -- cycle;    

    % the "cube"'s four other vertices
    \foreach \j in {0, 2}{%
      \foreach \k in {0, 3}{%
        \path
        ( {( \ry+.5*\rz*cos(360*(\b{\k}/\Nz)) )*cos(360*(\a{\j}/\Ny))},
        {-.5*\rz*sin(360*(\b{\k}/\Nz))},
        {( \ry+.5*\rz*cos(360*(\b{\k}/\Nz)) )*sin(360*(\a{\j}/\Ny))} )
        coordinate (Q-\j-\k);
      }
    }
    % faces of the cube inside the torus
    \filldraw[blue!80, very thin]
    (P-\a{0}-\b{0}) -- (Q-0-0) -- (Q-0-3) -- (P-\a{0}-\b{3}) -- cycle;
    \filldraw[B!50, very thin]
    (P-\a{0}-\b{0}) -- (Q-0-0) -- (Q-2-0) -- (P-\a{2}-\b{0}) -- cycle;

    % longitude cycles
    \foreach \j in {0, 2}{%
      \foreach \k [remember=\k as \prevk (initially 0)] in {1, ..., \Nz}{
        \ifthenelse{\test{\a{\j},\k}=1}{
          \draw[red] (P-\a{\j}-\prevk) -- (P-\a{\j}-\k);
        }{}
      }
    }
    % latitude cycles
    \foreach \k in {0, 3}{%
      \foreach \j [remember=\j as \prevj (initially 0)] in {1, ..., \Ny}{%
        \ifthenelse{\test{\j,\b{\k}}=1}{
          \draw[red] (P-\prevj-\b{\k}) -- (P-\j-\b{\k});
        }{}
      }
    }
  \end{scope}
  
  % coordinate system $Oxyz$; second layer
  \draw[green!50!black, -{Latex[length=5pt, width=5pt]}]
  (\ry+\rz, 0, 0) -- (8, 0, 0) node[right] {$x$};
  \draw[green!50!black, -{Latex[length=5pt, width=5pt]}]
  (0, 0, 0) -- (0, 6, 0) node[above] {$y$};
  \draw[green!50!black, -{Latex[length=5pt, width=5pt]}]
  (0, 0, \ry+\rz) -- (0, 0, 8) node[below left] {$z$};
\end{tikzpicture} 
\end{document}

在此处输入图片描述

相关内容