« home

Otto Cycle

physicsthermodynamicscetztikz

The Otto cycle is an idealized thermodynamic cycle of a typical spark ignition piston engine. It is the thermodynamic cycle most commonly found in automobile engines.


Otto Cycle

  Download

PNGPDFSVG

  Code

  LaTeX

otto-cycle.tex (37 lines)

\documentclass[tikz, svgnames]{standalone}

\usepackage{mathtools}
\usetikzlibrary{decorations.markings}

\def\V{10}
\def\p{7}

\tikzset{decoration={markings, mark=at position 0.5 with {\arrow{stealth}}}}

\begin{document}
\begin{tikzpicture}[thick]
  \draw[->] (0, 0) -- (0, \p) node[right] {$p$};
  \draw[->] (0, 0) -- (\V, 0) node[right] {$V$};

  \draw[dashed] (0, 0.9*\p) node[left] {$p_\text{max}$} -| (0.2*\V, 0) node[below] {$V_\text{min}$};

  \draw[dashed] (0, 0.2*\p) node[left] {$p_\text{min}$} -| (0.9*\V, 0) node[below] {$V_\text{max}$};

  \coordinate[label=above:1] (a) at (0.2*\V, 0.9*\p);
  \coordinate[label=right:2] (b) at (0.9*\V, 0.5*\p);
  \coordinate[label=right:3] (c) at (0.9*\V, 0.2*\p);
  \coordinate[label=left:4] (d) at (0.2*\V, 0.45*\p);

  \foreach \point in {a, b, c, d}
  \fill (\point) circle (3pt);

  \draw[ultra thick, DarkBlue] (a) edge[out=-40, in=180, looseness=0.7, postaction={decorate}]
  node[midway, above=2px] {$\Delta Q = 0$} (b) (b) -- (c)
  node[midway, right, blue] {$\Rightarrow Q_\text{out}$} (c)
  edge[out=180, in=-40, looseness=0.7, postaction={decorate}]
  node[midway, above=2px] {$\Delta Q = 0$} (d) (d) -- (a)
  node[midway, left, red] {$Q_\text{in} \Rightarrow$};

\end{tikzpicture}
\end{document}

  Typst

otto-cycle.typ (69 lines)

#import "@preview/cetz:0.3.2": canvas, draw
#import draw: line, content, circle, bezier

#set page(width: auto, height: auto, margin: 8pt)

#let (V, p) = (9, 6)

#canvas({
  // Draw axes
  line((0, 0), (0, p), mark: (end: "stealth", fill: black))
  content((0.2, p), $p$)
  line((0, 0), (V, 0), mark: (end: "stealth", fill: black))
  content((V + 0.2, 0), $V$)

  // Draw dashed lines for min/max values
  let p-max = 0.9 * p
  let p-min = 0.2 * p
  let V-min = 0.2 * V
  let V-max = 0.9 * V

  // Vertical dashed line for V-min
  line((0, p-max), (V-min, p-max), stroke: (dash: "dotted", thickness: 0.8pt))
  line((V-min, 0), (V-min, p-max), stroke: (dash: "dotted", thickness: 0.8pt))
  content((-0.5, p-max), $p_"max"$)
  content((V-min, -0.5), $V_"min"$)

  // Vertical dashed line for V-max
  line((0, p-min), (V-max, p-min), stroke: (dash: "dotted", thickness: 0.8pt))
  line((V-max, 0), (V-max, p-min), stroke: (dash: "dotted", thickness: 0.8pt))
  content((-0.5, p-min), $p_"min"$)
  content((V-max, -0.5), $V_"max"$)

  // Define points
  let a = (V-min, p-max)
  let b = (V-max, 0.5 * p)
  let c = (V-max, p-min)
  let d = (V-min, 0.45 * p)

  // Draw points
  for pt in (a, b, c, d) {
    circle(pt, radius: 3pt, fill: black)
  }

  // Add point labels
  content(a, [1], anchor: "south", padding: (bottom: 5pt))
  content(b, [2], anchor: "west", padding: (left: 5pt))
  content(c, [3], anchor: "north-west", padding: (left: 5pt))
  content(d, [4], anchor: "east", padding: (right: 5pt))

  // Draw cycle paths with arrows and labels
  // a -> b (adiabatic expansion)
  let arrow_style = (end: "stealth", fill: black)
  let stroke_style = (paint: rgb("#00008b"), thickness: 1.5pt)
  bezier(a, b, (b.at(0) - 5, b.at(1) + 1), stroke: stroke_style, mark: arrow_style)
  content(((a.at(0) + b.at(0)) / 2, (a.at(1) + b.at(1)) / 2 + 0.1), $Delta Q = 0$)

  // b -> c (heat rejection)
  line(b, c, mark: arrow_style, stroke: stroke_style)
  content((b.at(0) + 0.7, (b.at(1) + c.at(1)) / 2), text(fill: blue.darken(5%))[$arrow.r Q_"out"$])

  // c -> d (adiabatic compression)
  bezier(c, d, (d.at(0) + 2.4, d.at(1) - 1.3), stroke: stroke_style, mark: arrow_style)
  content(((c.at(0) + d.at(0)) / 2, (c.at(1) + d.at(1)) / 2 + 0.15), $Delta Q = 0$)

  // d -> a (heat addition)
  line(d, a, mark: arrow_style, stroke: stroke_style)
  content((d.at(0) - 0.6, (d.at(1) + a.at(1)) / 2), text(fill: red)[$Q_"in" arrow.r$])
})