# No. 406 (Brown 1868): "Mechanical means of describing parabolas, the base, altitude, focus, and directrix being given. Lay straight edge with
# near side coinciding with directrix, and square with stock against the same, so that the blade is parallel with the axis, and proceed with pencil in
# bight of thread, as in the preceding."
#
# Model (cm, a plan: the instrument lies flat on the drawing, so no gravity). The straight edge's near side is the directrix; the focus is 8 below it.
# The square's stock bears on the straight edge (real contact: the other hand holds it up against the edge with a light spring) and the square is slid
# along it by the hand, the one driven joint (to and fro, 5 either way). Its blade, parallel with the axis, reaches 20 below the directrix.
# A thread (a chain of links on real contact) is tied to a pin at the focus and to the blade's lower end, and is taken round the pencil; the thread
# is as long as the blade's reach. The pencil rides along the blade's edge (a slide on the square) and the hand draws it up towards the straight
# edge with a light spring, so the thread is kept tight: the pencil is held where it is by nothing but the thread. The thread from the blade's end
# lies along the edge, so the pencil's distance from the focus equals its distance from the directrix: a parabola.
# A light readout from the focus, pinned at the pencil, records its distance from the focus; it carries nothing.
# Generator: opencode-runs/batch13/gen406.py.
number: 406
slug: parabola-instrument
name: Mechanical means of describing parabolas
brown: "Mechanical means of describing parabolas, the base, altitude, focus, and directrix being given. Lay straight edge with near side coinciding with directrix, and square with stock against the same, so that the blade is parallel with the axis, and proceed with pencil in bight of thread, as in the preceding."
units: cm
sim: {timestep: 5e-05, integrator: implicitfast, iterations: 60, duration_s: 10.5, floor: false, gravity: 0}
bodies:
  - id: paper
    shape: part
    pos: [0, 0, 0]
    fixed: true
    friction: 0.05
    color: "#efe8d8"
    pieces:
      - {kind: poly, points: [[-16.0, -20.05], [-15.3333, -18.7444], [-15.3333, -18.6444], [-16.0, -19.95]], y: [0.55, 0.6], color: "#3a3632"}   # the parabola
      - {kind: poly, points: [[-15.3333, -18.7444], [-14.6667, -17.4944], [-14.6667, -17.3944], [-15.3333, -18.6444]], y: [0.55, 0.6], color: "#3a3632"}
      - {kind: poly, points: [[-14.6667, -17.4944], [-14.0, -16.3], [-14.0, -16.2], [-14.6667, -17.3944]], y: [0.55, 0.6], color: "#3a3632"}
      - {kind: poly, points: [[-14.0, -16.3], [-13.3333, -15.1611], [-13.3333, -15.0611], [-14.0, -16.2]], y: [0.55, 0.6], color: "#3a3632"}
      - {kind: poly, points: [[-13.3333, -15.1611], [-12.6667, -14.0778], [-12.6667, -13.9778], [-13.3333, -15.0611]], y: [0.55, 0.6], color: "#3a3632"}
      - {kind: poly, points: [[-12.6667, -14.0778], [-12.0, -13.05], [-12.0, -12.95], [-12.6667, -13.9778]], y: [0.55, 0.6], color: "#3a3632"}
      - {kind: poly, points: [[-12.0, -13.05], [-11.3333, -12.0778], [-11.3333, -11.9778], [-12.0, -12.95]], y: [0.55, 0.6], color: "#3a3632"}
      - {kind: poly, points: [[-11.3333, -12.0778], [-10.6667, -11.1611], [-10.6667, -11.0611], [-11.3333, -11.9778]], y: [0.55, 0.6], color: "#3a3632"}
      - {kind: poly, points: [[-10.6667, -11.1611], [-10.0, -10.3], [-10.0, -10.2], [-10.6667, -11.0611]], y: [0.55, 0.6], color: "#3a3632"}
      - {kind: poly, points: [[-10.0, -10.3], [-9.3333, -9.4944], [-9.3333, -9.3944], [-10.0, -10.2]], y: [0.55, 0.6], color: "#3a3632"}
      - {kind: poly, points: [[-9.3333, -9.4944], [-8.6667, -8.7444], [-8.6667, -8.6444], [-9.3333, -9.3944]], y: [0.55, 0.6], color: "#3a3632"}
      - {kind: poly, points: [[-8.6667, -8.7444], [-8.0, -8.05], [-8.0, -7.95], [-8.6667, -8.6444]], y: [0.55, 0.6], color: "#3a3632"}
      - {kind: poly, points: [[-8.0, -8.05], [-7.3333, -7.4111], [-7.3333, -7.3111], [-8.0, -7.95]], y: [0.55, 0.6], color: "#3a3632"}
      - {kind: poly, points: [[-7.3333, -7.4111], [-6.6667, -6.8278], [-6.6667, -6.7278], [-7.3333, -7.3111]], y: [0.55, 0.6], color: "#3a3632"}
      - {kind: poly, points: [[-6.6667, -6.8278], [-6.0, -6.3], [-6.0, -6.2], [-6.6667, -6.7278]], y: [0.55, 0.6], color: "#3a3632"}
      - {kind: poly, points: [[-6.0, -6.3], [-5.3333, -5.8278], [-5.3333, -5.7278], [-6.0, -6.2]], y: [0.55, 0.6], color: "#3a3632"}
      - {kind: poly, points: [[-5.3333, -5.8278], [-4.6667, -5.4111], [-4.6667, -5.3111], [-5.3333, -5.7278]], y: [0.55, 0.6], color: "#3a3632"}
      - {kind: poly, points: [[-4.6667, -5.4111], [-4.0, -5.05], [-4.0, -4.95], [-4.6667, -5.3111]], y: [0.55, 0.6], color: "#3a3632"}
      - {kind: poly, points: [[-4.0, -5.05], [-3.3333, -4.7444], [-3.3333, -4.6444], [-4.0, -4.95]], y: [0.55, 0.6], color: "#3a3632"}
      - {kind: poly, points: [[-3.3333, -4.7444], [-2.6667, -4.4944], [-2.6667, -4.3944], [-3.3333, -4.6444]], y: [0.55, 0.6], color: "#3a3632"}
      - {kind: poly, points: [[-2.6667, -4.4944], [-2.0, -4.3], [-2.0, -4.2], [-2.6667, -4.3944]], y: [0.55, 0.6], color: "#3a3632"}
      - {kind: poly, points: [[-2.0, -4.3], [-1.3333, -4.1611], [-1.3333, -4.0611], [-2.0, -4.2]], y: [0.55, 0.6], color: "#3a3632"}
      - {kind: poly, points: [[-1.3333, -4.1611], [-0.6667, -4.0778], [-0.6667, -3.9778], [-1.3333, -4.0611]], y: [0.55, 0.6], color: "#3a3632"}
      - {kind: poly, points: [[-0.6667, -4.0778], [0.0, -4.05], [0.0, -3.95], [-0.6667, -3.9778]], y: [0.55, 0.6], color: "#3a3632"}
      - {kind: poly, points: [[0.0, -4.05], [0.6667, -4.0778], [0.6667, -3.9778], [0.0, -3.95]], y: [0.55, 0.6], color: "#3a3632"}
      - {kind: poly, points: [[0.6667, -4.0778], [1.3333, -4.1611], [1.3333, -4.0611], [0.6667, -3.9778]], y: [0.55, 0.6], color: "#3a3632"}
      - {kind: poly, points: [[1.3333, -4.1611], [2.0, -4.3], [2.0, -4.2], [1.3333, -4.0611]], y: [0.55, 0.6], color: "#3a3632"}
      - {kind: poly, points: [[2.0, -4.3], [2.6667, -4.4944], [2.6667, -4.3944], [2.0, -4.2]], y: [0.55, 0.6], color: "#3a3632"}
      - {kind: poly, points: [[2.6667, -4.4944], [3.3333, -4.7444], [3.3333, -4.6444], [2.6667, -4.3944]], y: [0.55, 0.6], color: "#3a3632"}
      - {kind: poly, points: [[3.3333, -4.7444], [4.0, -5.05], [4.0, -4.95], [3.3333, -4.6444]], y: [0.55, 0.6], color: "#3a3632"}
      - {kind: poly, points: [[4.0, -5.05], [4.6667, -5.4111], [4.6667, -5.3111], [4.0, -4.95]], y: [0.55, 0.6], color: "#3a3632"}
      - {kind: poly, points: [[4.6667, -5.4111], [5.3333, -5.8278], [5.3333, -5.7278], [4.6667, -5.3111]], y: [0.55, 0.6], color: "#3a3632"}
      - {kind: poly, points: [[5.3333, -5.8278], [6.0, -6.3], [6.0, -6.2], [5.3333, -5.7278]], y: [0.55, 0.6], color: "#3a3632"}
      - {kind: poly, points: [[6.0, -6.3], [6.6667, -6.8278], [6.6667, -6.7278], [6.0, -6.2]], y: [0.55, 0.6], color: "#3a3632"}
      - {kind: poly, points: [[6.6667, -6.8278], [7.3333, -7.4111], [7.3333, -7.3111], [6.6667, -6.7278]], y: [0.55, 0.6], color: "#3a3632"}
      - {kind: poly, points: [[7.3333, -7.4111], [8.0, -8.05], [8.0, -7.95], [7.3333, -7.3111]], y: [0.55, 0.6], color: "#3a3632"}
      - {kind: poly, points: [[8.0, -8.05], [8.6667, -8.7444], [8.6667, -8.6444], [8.0, -7.95]], y: [0.55, 0.6], color: "#3a3632"}
      - {kind: poly, points: [[8.6667, -8.7444], [9.3333, -9.4944], [9.3333, -9.3944], [8.6667, -8.6444]], y: [0.55, 0.6], color: "#3a3632"}
      - {kind: poly, points: [[9.3333, -9.4944], [10.0, -10.3], [10.0, -10.2], [9.3333, -9.3944]], y: [0.55, 0.6], color: "#3a3632"}
      - {kind: poly, points: [[10.0, -10.3], [10.6667, -11.1611], [10.6667, -11.0611], [10.0, -10.2]], y: [0.55, 0.6], color: "#3a3632"}
      - {kind: poly, points: [[10.6667, -11.1611], [11.3333, -12.0778], [11.3333, -11.9778], [10.6667, -11.0611]], y: [0.55, 0.6], color: "#3a3632"}
      - {kind: poly, points: [[11.3333, -12.0778], [12.0, -13.05], [12.0, -12.95], [11.3333, -11.9778]], y: [0.55, 0.6], color: "#3a3632"}
      - {kind: poly, points: [[12.0, -13.05], [12.6667, -14.0778], [12.6667, -13.9778], [12.0, -12.95]], y: [0.55, 0.6], color: "#3a3632"}
      - {kind: poly, points: [[12.6667, -14.0778], [13.3333, -15.1611], [13.3333, -15.0611], [12.6667, -13.9778]], y: [0.55, 0.6], color: "#3a3632"}
      - {kind: poly, points: [[13.3333, -15.1611], [14.0, -16.3], [14.0, -16.2], [13.3333, -15.0611]], y: [0.55, 0.6], color: "#3a3632"}
      - {kind: poly, points: [[14.0, -16.3], [14.6667, -17.4944], [14.6667, -17.3944], [14.0, -16.2]], y: [0.55, 0.6], color: "#3a3632"}
      - {kind: poly, points: [[14.6667, -17.4944], [15.3333, -18.7444], [15.3333, -18.6444], [14.6667, -17.3944]], y: [0.55, 0.6], color: "#3a3632"}
      - {kind: poly, points: [[15.3333, -18.7444], [16.0, -20.05], [16.0, -19.95], [15.3333, -18.6444]], y: [0.55, 0.6], color: "#3a3632"}
      - {kind: poly, points: [[-0.03, -1.0], [0.03, -1.0], [0.03, 0.0], [-0.03, 0.0]], y: [0.55, 0.6], color: "#8f8a80"}   # the axis, dotted
      - {kind: poly, points: [[-0.03, -3.0], [0.03, -3.0], [0.03, -2.0], [-0.03, -2.0]], y: [0.55, 0.6], color: "#8f8a80"}
      - {kind: poly, points: [[-0.03, -5.0], [0.03, -5.0], [0.03, -4.0], [-0.03, -4.0]], y: [0.55, 0.6], color: "#8f8a80"}
      - {kind: poly, points: [[-0.03, -7.0], [0.03, -7.0], [0.03, -6.0], [-0.03, -6.0]], y: [0.55, 0.6], color: "#8f8a80"}
      - {kind: poly, points: [[-0.03, -9.0], [0.03, -9.0], [0.03, -8.0], [-0.03, -8.0]], y: [0.55, 0.6], color: "#8f8a80"}
      - {kind: poly, points: [[-0.03, -11.0], [0.03, -11.0], [0.03, -10.0], [-0.03, -10.0]], y: [0.55, 0.6], color: "#8f8a80"}
      - {kind: poly, points: [[-0.03, -13.0], [0.03, -13.0], [0.03, -12.0], [-0.03, -12.0]], y: [0.55, 0.6], color: "#8f8a80"}
      - {kind: poly, points: [[-0.03, -15.0], [0.03, -15.0], [0.03, -14.0], [-0.03, -14.0]], y: [0.55, 0.6], color: "#8f8a80"}
      - {kind: poly, points: [[-0.03, -17.0], [0.03, -17.0], [0.03, -16.0], [-0.03, -16.0]], y: [0.55, 0.6], color: "#8f8a80"}
      - {kind: poly, points: [[-0.03, -19.0], [0.03, -19.0], [0.03, -18.0], [-0.03, -18.0]], y: [0.55, 0.6], color: "#8f8a80"}
      - {kind: poly, points: [[-0.03, -21.0], [0.03, -21.0], [0.03, -20.0], [-0.03, -20.0]], y: [0.55, 0.6], color: "#8f8a80"}
      - {kind: poly, points: [[-26, 0], [16, 0], [16, 3], [-26, 3]], y: [-0.4, 0.5], collide: 1, color: "#e6dcc4"}   # the straight edge, its near side on the directrix
      - {kind: disc, center: [0, -8], radius: 0.3, y: [-1.2, 0.55], color: "#5c5244"}   # the pin at the focus, the thread tied to it
  - {id: car_x, shape: part, pos: [-9.4500, 0, -0.8], mass: 0.002, pieces: [{kind: rod, from: [-9.4500, -3, -0.8], to: [-9.4500, -2.95, -0.8], radius: 0.05}]}
  - id: square
    shape: part
    pos: [-9.4500, 0, -0.8]
    mount: car_x
    density: 1400
    friction: 0.05
    color: "#d8ccb0"
    pieces:
      - {kind: poly, points: [[-15.65, -1.6], [-8.95, -1.6], [-8.95, 0.0], [-15.65, 0.0]], y: [-0.4, 0.4], collide: 2}   # the stock, against the straight edge
      - {kind: poly, points: [[-11.15, -21.0], [-9.55, -21.0], [-9.55, -1.6], [-11.15, -1.6]], y: [-0.3, 0.3]}   # the blade, parallel with the axis
      - {kind: disc, center: [-9.4500, -20.0000], radius: 0.25, y: [-0.6, 0.3], color: "#8f8a80"}   # the thread's tie at its end
  - {id: pencil, shape: pulley, radius: 0.35, width: 0.8, pos: [-9.0000, 0, -9.0625], mount: square, mass: 0.004, spokes: 0, web: true, flange: 0.35, groove: 0.4, hub: 0.15, touch: {side: 1, friction: 0.05}, color: "#3a3632"}
  - {id: rd_arm, shape: part, pos: [0, 0, -8], mass: 0.002, pieces: [{kind: rod, from: [0, -2, -8], to: [0, -1.95, -8], radius: 0.05}]}
  - {id: rd_rad, shape: part, pos: [-9.0000, 0, -9.0625], mount: rd_arm, mass: 0.002, pieces: [{kind: rod, from: [-9.0000, -2, -9.0625], to: [-9.0000, -1.95, -9.0625], radius: 0.05}]}
pins:
  - {id: p_read, a: rd_rad, b: pencil, at: [-9.0000, 0, -9.0625]}   # the readout at the pencil
joints:
  - {id: j_x, type: slide, body: car_x, axis: [1, 0, 0], damping: 0.002}   # the one driven joint: the hand slides the square along the straight edge
  - {id: j_y, type: slide, body: square, axis: [0, 0, 1], stiffness: 60, springref: 3, damping: 0.5}   # the stock held up against the straight edge
  - {id: j_s, type: slide, body: pencil, axis: [0, 0, -1], stiffness: 2, springref: -30, damping: 0.05}   # the pencil down the blade's edge, drawn up towards the straight edge
  - {id: j_rd, type: hinge, body: rd_arm, axis: [0, 1, 0]}   # readout: the pencil's bearing from the focus
  - {id: j_r, type: slide, body: rd_rad, axis: [-0.993103, 0, -0.117241]}   # readout: the pencil's distance from the focus, less 9.062
cords:
  - id: thread
    from: {body: paper, at: [0, 0, -8]}
    to: {body: square, at: [-9.4500, 0, -20.0000]}
    over: [pencil]
    under: [pencil]
    links: 70
    segments: 1
    root_damping: 0.0001
    joint_armature: 1e-06
    thickness: 0.2
    density: 5000
    stiffness: 60000
    pretension: 1
    damping: 2
    bend_damping: 1e-06
    friction: 0.05
    color: "#7a4f2a"
contact: {solref: [0.002, 1], solimp: [0.95, 0.99, 0.0005], margin: 0}
driver: {joint: j_x, kind: velocity, rpm: 0, swing: {amplitude: 0.0571, hz: 0.2}, kv: 800, max_torque: 20}
checks:
  - {type: follow, out: j_r, in: j_s, expect: 1.046, tol: 0.03, min_r2: 0.995, settle_s: 0.5, window_s: 6}   # the pencil goes from the focus as far as it goes from the directrix: slope 1 for a point; 1.046 for the thread wrapping this 0.45 pencil (gen406.py)
  - {type: amplitude, joint: j_x, min: 0.035, max: 0.08, sustain: 0.7, settle_s: 0.5, window_s: 6}   # the square slid well along the straight edge
  - {type: position, joint: j_y, min: -0.001, max: 0.001, settle_s: 0.5, window_s: 6}   # the stock stays against the straight edge
  - {type: penetration, max: 0.004, settle_s: 0.5}
camera: {target: [-5, 0, -9], position: [-5, -80, -9], fov: 30}
display:
  output: j_r
  labels: {j_x: "The hand sliding the square (driver)", j_y: "The stock against the straight edge", j_s: "Pencil down the blade", j_rd: "Pencil's bearing from the focus", j_r: "Pencil's distance from the focus"}

