TikZ:在循环顶部绘制一辆购物车

TikZ:在循环顶部绘制一辆购物车

我正在尝试在环路顶部绘制一辆手推车。我有一个系统,其中一辆手推车从斜坡上滚下来并遇到一个环路。然后我想在手推车到达环路顶点时查看它。

我遇到的问题是如何绘制接触环的轮子,以便它们与环相切。

这是更大图景的图像。

在此处输入图片描述

现在这就是我目前所知道的购物车和循环顶部之间的相互作用。

\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}

在此处输入图片描述

相关内容