有人知道如何用渐近线在圆环上画一个小楔子吗?
这是我目前所拥有的,但我希望能够以某种方式为我的楔形立方体添加阴影。然而,目前我的立方体由许多部分组成,所以我真的不知道该怎么做。
这是我目前的代码。你会注意到,它的第一部分(实际上看起来不错的部分!)是相当厚颜无耻地直接从第二个答案中摘录的这里。我更喜欢将代码放在 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 中恢复它们协调定义,它们被计算(太)多次;代码可以改进。
- 观察者的视点由单位向量定义瓦指向观察者。其组成部分包括\毒素,\玩具, 和\托兹, 在哪里
\tox = x_瓦= 正弦\经度 余弦\纬度
\玩具= y_瓦= 正弦\纬度
\toz = z_瓦= 余弦\经度 余弦\纬度.
角度\长和\纬度分别代表经度和纬度。
- 屏幕(绘制图像的平面)是通过原点并正交于瓦. 诱导屏幕坐标系的正交基是(你,五,瓦), 在哪里
你= ( 余弦, 0 , - 正弦)
五= (- 正弦\经度 正弦\纬度, 余弦\纬度, - 余弦\经度 正弦\纬度)
注意初始坐标系是氧,这样当\经度=\纬度=0,盎司是水平的,被观察者视为一个点,并且牛是水平的,并且指向观察者的右侧。因此,你平行于奥克斯; 尤其\纬度必须与直角不同。
要点(1,0,0),(0,1,0), 和(0,0,1)投影到绘图的全局选项中描述的点上x={(\newxx 厘米, \newxy 厘米)}等,例如,\newxx = <(1,0,0),你>, \newxy = <(1,0,0),五>。
我一直在思考这些问题,因为绘制 3D 物体取决于观察者的位置向量,瓦。
- 我们将圆环视为围绕奥伊半径为圆的轴\rz在飞机上氧. 圆心到奥伊是\ry。因此,我们的网格由点定义(P-\j-\k);作为 3D 点,它们的坐标与往常一样(参见代码)。我只想指出是-坐标有一个减号,
-\rz sin(360(\k/\Nz)), 和0<=\k<=\Nz。
之所以存在,是因为经度周期上的四边形应视为顺时针方向(从 3 点开始)。这种选择是正确的,当瓦属于第一象限。
为了\j固定的,这些点描述一个经度周期(半径为\rz); 为了\k固定的点描述了一个纬度周期。特别是,最长的纬度周期(圆环与圆心的交点)奥兹克平面)获得\k=0。
- 绘制的网格四边形由以下函数给出已看到返回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}