|
| 1 | +#import "@preview/cetz:0.3.4" |
| 2 | +#import "@preview/pull-eh:0.1.0" |
| 3 | +#import cetz.draw: on-layer, line, content |
| 4 | +#import pull-eh: wind, ccw, cw |
| 5 | + |
| 6 | +#set page(width: auto, height: auto, margin: 5mm) |
| 7 | +#set text(0.9em) |
| 8 | + |
| 9 | +#let block(coord, (w, h), ..args) = { |
| 10 | + // use the given coord as the center of the rect |
| 11 | + let tl = (rel: (-w / 2, -h / 2), to: coord) |
| 12 | + let br = (rel: (w, h)) |
| 13 | + cetz.draw.rect(tl, br, fill: white, ..args) |
| 14 | +} |
| 15 | +#let fixing(coord, len, ..args) = { |
| 16 | + cetz.draw.line(stroke: 3pt, coord, (rel: len, to: coord)) |
| 17 | + cetz.draw.circle(coord, fill: black, radius: 0.2) |
| 18 | +} |
| 19 | +#let pulley(..args) = { |
| 20 | + cetz.draw.circle(fill: green, stroke: none, ..args) |
| 21 | +} |
| 22 | + |
| 23 | +#let force(coord, direction, ..args) = { |
| 24 | + let mark = (end: (symbol: ">", length: 0.12cm, width: 0.15cm)) |
| 25 | + cetz.draw.line(coord, (rel: direction), stroke: 4pt, mark: mark, ..args) |
| 26 | +} |
| 27 | + |
| 28 | +#let gun-tackle = cetz.canvas({ |
| 29 | + // the pulleys; on the default layer |
| 30 | + pulley(name: "pulley1", (1, 4)) |
| 31 | + pulley(name: "pulley2", (1, 0)) |
| 32 | + // the "fixed" parts of the diagram: ceiling and blocks. The blocks wrap around the pulleys |
| 33 | + // and thus hide them and the rope |
| 34 | + on-layer( |
| 35 | + 1, |
| 36 | + { |
| 37 | + block(name: "block1", "pulley1", (0.4, 2.4)) |
| 38 | + block(name: "block2", "pulley2", (0.4, 2.4)) |
| 39 | + line(stroke: 2pt, (rel: (-1.4, 0), to: "block1.north"), (rel: (1.4, 0), to: "block1.north")) |
| 40 | + }, |
| 41 | + ) |
| 42 | + // the rope; drawn over the pulleys, but hidden by the blocks |
| 43 | + wind( |
| 44 | + stroke: 1.5pt, |
| 45 | + (rel: (1.5, -2.5), to: "pulley1"), |
| 46 | + (coord: "pulley1", radius: 1) + ccw, |
| 47 | + (coord: "pulley2", radius: 1) + ccw, |
| 48 | + "block1.south", |
| 49 | + ) |
| 50 | + // the labels of the diagram |
| 51 | + on-layer( |
| 52 | + 1, |
| 53 | + { |
| 54 | + content((rel: (-1.4, -2), to: "pulley1"))[50N] |
| 55 | + content((rel: (-0.1, -2), to: "pulley1"))[50N] |
| 56 | + content((rel: (1.7, -1.5), to: "pulley1"))[50N] |
| 57 | + |
| 58 | + force((rel: (0, 0.4), to: "pulley1.north"), (90deg, 0.8), name: "f-ceiling") |
| 59 | + content((rel: (0.7, 0), to: "f-ceiling"))[150N] |
| 60 | + |
| 61 | + force((rel: (0, -0.4), to: "pulley2.south"), (-90deg, 0.8), name: "f-load") |
| 62 | + content((rel: (0.7, 0), to: "f-load"))[100N] |
| 63 | + |
| 64 | + force((rel: (1.54, -2.7), to: "pulley1"), (-78deg, 0.8), name: "f-rope") |
| 65 | + content((rel: (0.65, 0), to: "f-rope"))[50N] |
| 66 | + }, |
| 67 | + ) |
| 68 | +}) |
| 69 | + |
| 70 | +#let separated = cetz.canvas({ |
| 71 | + let block1 = (4, 5.2) |
| 72 | + |
| 73 | + // the pulleys; on the default layer |
| 74 | + pulley(name: "pulley1", (1, 4)) |
| 75 | + pulley(name: "pulley2", (3, 0)) |
| 76 | + // the "fixed" parts of the diagram: ceiling and blocks. The blocks wrap around the pulleys |
| 77 | + // and thus hide them and the rope |
| 78 | + on-layer( |
| 79 | + 1, |
| 80 | + { |
| 81 | + fixing("pulley1.center", (0, 1.2)) |
| 82 | + fixing("pulley2.center", (0, -1.2)) |
| 83 | + line(stroke: 2pt, (rel: (-4.4, 0), to: block1), (rel: (0.4, 0), to: block1)) |
| 84 | + }, |
| 85 | + ) |
| 86 | + // the rope; drawn over the pulleys, but hidden by the blocks |
| 87 | + wind( |
| 88 | + stroke: 1.5pt, |
| 89 | + (rel: (-1.5, -2.5), to: "pulley1"), |
| 90 | + (coord: "pulley1", radius: 1) + cw, |
| 91 | + (coord: "pulley2", radius: 1) + ccw, |
| 92 | + block1, |
| 93 | + ) |
| 94 | + // the labels of the diagram |
| 95 | + on-layer( |
| 96 | + 1, |
| 97 | + { |
| 98 | + content((rel: (3.4, -2), to: "pulley1"))[50N] |
| 99 | + content((rel: (1.4, -2), to: "pulley1"))[50N] |
| 100 | + content((rel: (-1.7, -1.5), to: "pulley1"))[50N] |
| 101 | + |
| 102 | + force((rel: (1.5, 0.4), to: "pulley1.north"), (90deg, 0.8), name: "f-ceiling") |
| 103 | + content((rel: (0.7, 0), to: "f-ceiling"))[150N] |
| 104 | + |
| 105 | + force((rel: (0, -0.4), to: "pulley2.south"), (-90deg, 0.8), name: "f-load") |
| 106 | + content((rel: (0.7, 0), to: "f-load"))[100N] |
| 107 | + |
| 108 | + force((rel: (-1.54, -2.7), to: "pulley1"), (-102deg, 0.8), name: "f-rope") |
| 109 | + content((rel: (0.65, 0), to: "f-rope"))[50N] |
| 110 | + }, |
| 111 | + ) |
| 112 | +}) |
| 113 | + |
| 114 | +#grid( |
| 115 | + columns: 2, |
| 116 | + column-gutter: 2cm, |
| 117 | + gun-tackle, separated, |
| 118 | +) |
0 commit comments