--- jupyter: description: 'A chain link plate as a 2D CAD exercise: a dimensioned drawing to model in planex2d or any CAD system, a solution from circles trimmed to the outline, and the area and centroid to check a model against.' --- # Chain link plate A chain link plate joins two pins of a roller chain. It has two eyes around the pin holes and a waist between them whose flanks are arcs tangent to both eyes. Model the plate from the drawing in planex2d or in any CAD system, then check its area and centroid against the values at the end of the page. A solution in planex2d follows. ![The chain link plate exercise: a dimensioned drawing of a plate with two eyes and a waist of two concave arcs](../_static/gallery/chain-plate.png){.result} ```python import math import planex as px ``` ```python nbsphinx="hidden" from docs_figures import Row ``` ## The circles The plate is drawn on four circles, the two eyes, of radius 15 and 50 apart, and the two flanks, of radius 40, each tangent to both eyes, one above the axis and one below it. `reverse=True` picks the flank below. With `auto_constraint=True`, the flanks stay tangent to the eyes when a dimension changes (Figure 1). ```python plate = px.Sketch(auto_constraint=True) plate.Circle(15, id="left_eye") plate.Circle(15, center=(50, 0), id="right_eye") plate.Circle(40, id="upper_flank", tangent=("left_eye", "right_eye")) plate.Circle(40, id="lower_flank", tangent=("left_eye", "right_eye"), reverse=True) print("upper flank center", tuple(round(v, 3) for v in plate.Location("upper_flank.center"))) ``` ```python nbsphinx="hide-input" circles = ("left_eye", "right_eye", "upper_flank", "lower_flank") Row((plate, "The eyes and the two flanks tangent to them", {"fill": False, "marks": [plate.Location(c + ".center") for c in circles], "rotate": 90}), caption="The circles, their centers marked") ``` ## Trimming Each circle is cut where it touches the others, and `Trim` turns the piece nearest to a point into construction. That is the inner piece of each eye, toward the other eye, and the outer piece of each flank, away from the plate. What stays is the outline. The pin holes of 12 go around the centers of the eyes (Figure 2). ```python plate.Trim(("left_eye", (20, 0))) # the piece nearest to (20, 0), the inner one, becomes construction plate.Trim(("right_eye", (30, 0))) plate.Trim(("upper_flank", (25, 100))) plate.Trim(("lower_flank", (25, -100))) plate.Circle(6, concentric="left_eye", id="left_hole") plate.Circle(6, concentric="right_eye", id="right_hole"); ``` ```python nbsphinx="hide-input" Row((plate, "The outline, the trimmed pieces dashed", {"fill": False, "rotate": 90}), caption="The trimmed outline") ``` ## The dimensions The left eye's center is the origin, and the right eye's center lies on the horizontal axis. The second eye, the second flank and the second hole are equal to the first ones, so the sketch carries each size once, as the drawing gives it. With these, nothing in the sketch is left free (Figure 3): ```python plate.Constrain("left_eye.center", "origin", px.Coincident) plate.Constrain("right_eye.center", "H", px.Coincident) plate.Constrain("left_eye.center", "right_eye.center", px.Distance, 50, id="pitch") plate.Constrain("left_eye", px.Radius, 15, id="eye_r") plate.Constrain("right_eye", "left_eye", px.Equal) plate.Constrain("upper_flank", px.Radius, 40, id="flank_r") plate.Constrain("lower_flank", "upper_flank", px.Equal) plate.Constrain("left_hole", px.Diameter, 12, id="hole_d") plate.Constrain("right_hole", "left_hole", px.Equal) print("status", plate.status, "| degrees of freedom", plate.dof) ``` ```python nbsphinx="hide-input" Row((plate, "Every dimension and tie of the sketch", {"constraints": True}), caption="The fully constrained sketch", height=60) ``` ## The checks These are the area and the centroid of the plate, with the left eye's center at the origin, to compare with your own model. The plate is symmetric about the axis and about the middle between the eyes, so its centroid lies at that middle (Figure 4): ```python face = plate.Face() c = face.center print("area", round(face.mass, 2), "mm²") print("centroid", round(c[0], 2), "on the axis, off it by", round(abs(c[1]), 6)) ``` ```python nbsphinx="hide-input" Row((face, "The plate, its centroid marked", {"marks": [c[:2]]}), caption="The plate") ``` The plate as DXF in millimeters, for another CAD system or a laser cutter: ```python plate.WriteDXF("chain_plate.dxf", unit=px.mm, scale=1) # scale=1: the numbers as they are ``` The plate as DXF: [chain_plate.dxf](chain_plate.dxf) ```python nbsphinx="hidden" import sys sys.path.insert(0, "..") import matplotlib.pyplot as plt from drawings import SheetFigure, View from gallery import save_figure view = View([(plate, {"pitch": -28, "eye_r": (135, "outside", 2), "flank_r": (270, "inside", 2), "hole_d": (225, "leader", 2)}, {"left_hole": "lines", "right_hole": "lines"})], axes=[((-20, 0), (70, 0), (0, 0))]) drawing = SheetFigure([view], margin=20, notes=("planex2d.org", "2D exercise 05")) print("scale 1 :", round(1 / drawing.planex_scale), "| paper", [round(v * 25.4) for v in drawing.get_size_inches()], "mm") save_figure(drawing, "chain-plate", dpi=200) plt.close(drawing) ```