我正在尝试在环路顶部绘制一辆手推车。我有一个系统,其中一辆手推车从斜坡上滚下来并遇到一个环路。然后我想在手推车到达环路顶点时查看它。
我遇到的问题是如何绘制接触环的轮子,以便它们与环相切。
这是更大图景的图像。
现在这就是我目前所知道的购物车和循环顶部之间的相互作用。
\documentclass[tikz]{standalone}
\usetikzlibrary{intersections}
\begin{document}
\begin{tikzpicture}
\draw[name path = circ] (0, 0) circle[radius = 0.05];
\path[name path = line] (-0.1, .04) -- +(0.2, 0);
\path[name intersections = {of = circ and line}];
\coordinate (P1) at (intersection-1);
\coordinate (P1) at (intersection-2);
\end{tikzpicture}
\end{document}
我画了一条与环相交的路径,并标记了点。我将其作为车轮与环相切的线。因此,如果一切都基于这些点,我们可以调整路径以获得与顶部所需的距离,从而使图像看起来最好。
答案1
画车轮并不难,因为它们的中心位于环的半径内。问题在于画出汽车的其余部分。在当前形式下(在您的绘图中),它看起来像车轮顶部的块。它会如何滚动?车轮如何连接到车身上?
我认为更合适的方法是将块绘制在中心而不是在车轮顶部。使用这种方法,以下代码可以解决问题。如果您希望块位于车轮顶部,如图所示,只需取消注释标记的行即可。然而,在我看来,结果更丑陋。
代码:
(更新后,为矩形添加了半透明效果,这样车轮就会被部分遮挡。感谢 Charles Staats 的建议)
\def\loopradius{4cm}
\def\wheelradius{5mm}
\usetikzlibrary{intersections,calc}
\begin{tikzpicture}[thick]
\coordinate (center) at (0,0);
\draw[name path = circ] (center) circle[radius = \loopradius];
\path[name path = line] ($(-10, 0.87*\loopradius)$) -- +(20, 0);
\path[name intersections = {of = circ and line}];
\coordinate (P1) at (intersection-1);
\coordinate (P2) at (intersection-2);
\coordinate (C1) at ($(P1)!\wheelradius!(center)$);
\coordinate (C2) at ($(P2)!\wheelradius!(center)$);
\foreach \p in {1,2} {
\draw[red] (C\p) circle (\wheelradius);
}
%\coordinate (C1) at ($(P1)!2*\wheelradius!(center)$);
%\coordinate (C2) at ($(P2)!2*\wheelradius!(center)$);
\draw[red, fill=white, fill opacity=0.85]
let \p1 = ($(C2)-(C1)$),
\n1 = {veclen(\p1)}
in
(C2) rectangle +($(\n1, -0.4*\n1)$)
node[midway] {M};
\end{tikzpicture}
结果:
答案2
这是充分利用 Asymptote 计算能力的版本。代码非常稳定,如果您更改车轮之间的距离和/或车轮的半径,它仍能正常工作。
\documentclass[margin=10pt,convert]{standalone}
\usepackage{asypictureB}
\begin{document}
\begin{asypicture}{name=cart_on_loop}
settings.outformat="pdf";
unitsize(1cm);
import graph;
path loop = (-3,0) --- (-1,0) .. (0,4){left} .. (1,0) --- (3,0);
real wheelradius = 0.05, wheeldistance = 0.5, cartheight = 0.3;
//Where will a wheel center be when it's tangent to the loop at path time t?
pair wheelcenter(real t) {
return point(loop, t) + wheelradius*(rotate(90)*dir(loop,t));
}
//This path is for computation, not drawing:
path wheelpath = graph(wheelcenter, 0, length(loop), operator ..);
picture cart = currentpicture.copy();
draw(cart, circle(c=(0,0), r=wheelradius));
draw(cart, circle(c=(wheeldistance, 0), r=wheelradius));
draw(cart, box((0, wheelradius), (wheeldistance, wheelradius+cartheight)));
label(cart, "$M$", align=0.2N, position=(wheeldistance/2, wheelradius));
void drawcart(pair trailingwheel, pair leadingwheel = trailingwheel + (wheeldistance, 0)) {
transform T = identity();
pair vector = leadingwheel - trailingwheel;
real angle = degrees(atan2(vector.y, vector.x));
T = rotate(angle)*T;
T = scale(length(vector) / wheeldistance)*T;
T = shift(trailingwheel)*T;
add(T*cart);
}
//t is specified in arclength
void drawcart(real t) {
pair trailingwheel = arcpoint(wheelpath, t);
pair estimateleading = arcpoint(wheelpath, t + wheeldistance);
path samedist = circle(c=trailingwheel, r=wheeldistance);
pair[] intersections = intersectionpoints(samedist, wheelpath);
pair leadingwheel = intersections[0];
for (pair candidate : intersections) {
if (length(candidate - estimateleading) < length(leadingwheel - estimateleading))
leadingwheel = candidate;
}
drawcart(trailingwheel, leadingwheel);
}
//Draw the loop:
draw(subpath(loop, 0, length(loop)/2));
draw(subpath(loop, length(loop)/2, length(loop)), white + linewidth(2pt) + squarecap);
draw(subpath(loop, length(loop)/2, length(loop)));
/* Find the times when the center of the wheel has x = wheeldistance/2.
* There will be three such times (entering loop, at the top, leaving loop),
* indexed by 0, 1, 2. We want the middle one.
*/
real patht = times(wheelpath, wheeldistance/2)[1];
real t = arclength(subpath(wheelpath,0,patht));
drawcart(t);
//Draw a couple more carts at random places
drawcart(0.2);
drawcart(3.3);
\end{asypicture}
\end{document}
答案3
只是为了和 PSTricks 一起玩。
\documentclass[pstricks,border=12pt]{standalone}
\usepackage{pst-node}
\begin{document}
\foreach \i in {0,15,...,345}{%
\begin{pspicture}(-2,-2)(2,2)
\pscircle{2}
\pnodes{A}(!1.9 \i\space 30 add PtoC)(!1.9 \i\space PtoC)
\pspolygon*[linecolor=gray](A0)(A1)([offset=.5]{A0}A1)([offset=-.5]{A1}A0)
\qdisk(A0){.1}\qdisk(A1){.1}
\end{pspicture}}
\end{document}
冰冻动画
\documentclass[pstricks,border=12pt]{standalone}
\usepackage{pst-node}
\begin{document}
\begin{pspicture}(-2,-2)(2,2)
\pscircle{2}
\pnodes{A}(!1.9 105 PtoC)(!1.9 75 PtoC)
\pspolygon*[linecolor=gray](A0)(A1)([offset=.5]{A0}A1)([offset=-.5]{A1}A0)
\qdisk(A0){.1}\qdisk(A1){.1}
\end{pspicture}
\end{document}
TikZ 版本
\documentclass[tikz,border=12pt]{standalone}
\usetikzlibrary{calc}
\begin{document}
\foreach \i in {0,15,...,345}{%
\begin{tikzpicture}
\draw (0,0) circle (2);
\coordinate (A0) at (\i+30:1.9);
\coordinate (A1) at (\i:1.9);
\fill [gray] (A0) -- (A1) -- ($(A1)!.5!90:(A0)$) -- ($(A0)!.5!-90:(A1)$) -- cycle;
\fill (A0) circle (.1) (A1) circle (.1);
\end{tikzpicture}}
\end{document}
答案4
几何图形是简单易懂的东西。实际上不需要库,math
但代码看起来更简洁一些。
\documentclass[tikz,border=5]{standalone}
\usetikzlibrary{math}
\begin{document}
\begin{tikzpicture}
\tikzmath{
\R = 2; % Loop radius
\r = 1/8; % Wheel radius
\w = 1; % Cart width
\h = 1/2; % Cart height
%
% Calculate the angle from the vertical
% of the radius of the loop that passes
% through the center of the wheels.
\a = asin((\w/2)/(\R-\r));
% Calculate the vertical position of the cart wheels;
\S = (\R-\r)*cos(\a);
}
\draw circle [radius=\R];
\draw (-\w/2,\S-\h-\r) rectangle ++(\w, \h);
\node at (0, \S-\h/2-\r) {$M$};
\draw [fill=white] (-\w/2,\S) circle [radius=\r] (\w/2,\S) circle [radius=\r];
\end{tikzpicture}
\end{document}