--- jupyter: description: 'A series of flanges in three sizes as a 2D CAD exercise: a tabulated drawing with its sizes as letters and a table, to model in planex2d or any CAD system, a solution from one sketch with named dimensions and a rule for its bolt circle, updated to each size, and the areas to check a model against.' --- # Flange series A flange is made in several sizes that differ in their numbers but not in their shape, and one tabulated drawing gives them all: the dimensions are letters, and a table gives each size's values. A parametric model works the same way. One sketch carries the letters as named dimensions, a rule ties the bolt circle to them, and each size is one update of the sketch. Model the flange in its three sizes from the drawing in planex2d or in any CAD system, then check their areas against the values at the end of the page. A solution in planex2d follows. ![The flange series exercise: a tabulated drawing of a round flange with a bore and holes on a bolt circle, its dimensions as letters, and a table of three sizes](../_static/gallery/flange-series.png){.result} ```python import math import planex as px ``` ```python nbsphinx="hidden" from docs_figures import Row ``` ## The sketch The flange is drawn as circles around the origin, roughly at size A, the outside, the bore and the first hole, on the $x$ axis. The dimensions get the drawing's letters as their ids, the outside's diameter `D`, the bore's `d` and the hole's `l`. The bolt circle, of diameter $k$, lies midway between the bore and the outside in every size, $k = (D + d) / 2$. `Expression` states that rule for the hole's center, whose $h$ coordinate is half of $k$. `CircularPattern` repeats the hole around the origin, its number of holes the dimension `holes.count`. With these, nothing in the sketch is left free (Figure 1): ```python flange = px.Sketch(auto_constraint=True) flange.Circle(50, id="outside") flange.Circle(15, id="bore") flange.Circle(5.5, center=(32, 1), id="hole") flange.Constrain("outside.center", "origin", px.Coincident) flange.Constrain("hole.center", "H", px.Coincident) flange.Constrain("outside", px.Diameter, 100, id="D") # the drawing's letter as the dimension's id flange.Constrain("bore", px.Diameter, 30, id="d") flange.Constrain("hole", px.Diameter, 11, id="l") flange.Expression("hole.center.h = (D + d) / 4", id="bolt_circle") # half of k = (D + d) / 2 flange.CircularPattern(["hole"], "origin", 4, id="holes") # its count, holes.count, is a dimension too print("status", flange.status, "| degrees of freedom", flange.dof) ``` ```python nbsphinx="hide-input" Row((flange, "Every dimension and tie of the sketch, at size A", {"constraints": True}), caption="The fully constrained sketch") ``` ## The sizes The table of the drawing gives the three sizes. `Update` sets the dimensions of a size and solves the sketch again. The bolt circle follows its rule, and the pattern takes its new number of holes, spaced evenly (Figure 2): ```python sizes = {"A": {"D": 100, "d": 30, "l": 11, "holes.count": 4}, "B": {"D": 125, "d": 45, "l": 13.5, "holes.count": 4}, "C": {"D": 160, "d": 60, "l": 13.5, "holes.count": 8}} faces = {} for name, size in sizes.items(): flange.Update(size) faces[name] = flange.Face() print(name, "status", flange.status, "| bolt circle k", round(2 * flange.Location("hole.center")[0], 6), "| holes", flange["holes.count"], round(flange["holes.angle"], 6), "° apart") ``` ```python nbsphinx="hide-input" Row(*[(face, f"Size {name}") for name, face in faces.items()], caption="The three sizes, at the same scale") ``` ## The checks These are the areas, to compare with your own model. Each size is its outside less the bore and the $n$ holes, $\tfrac{\pi}{4} \cdot (D^2 - d^2 - n\,l^2)$. Every flange is symmetric about the $x$ axis and under a half turn, so its centroid is the center: ```python for name, size in sizes.items(): face = faces[name] exact = math.pi / 4 * (size["D"] ** 2 - size["d"] ** 2 - size["holes.count"] * size["l"] ** 2) print(name, "area", round(face.mass, 2), "mm², exact", round(exact, 2), "| centroid", tuple(round(v, 6) for v in face.center[:2])) ``` The three flanges as DXF in millimeters, for another CAD system or a laser cutter: ```python for name, face in faces.items(): face.WriteDXF(f"flange_{name}.dxf", unit=px.mm, scale=1) # scale=1: the numbers as they are ``` The flanges as DXF: [flange_A.dxf](flange_A.dxf), [flange_B.dxf](flange_B.dxf), [flange_C.dxf](flange_C.dxf) ```python nbsphinx="hidden" import sys sys.path.insert(0, "..") import matplotlib.pyplot as plt from drawings import LANDSCAPE, SheetFigure, Table, View from gallery import save_figure # the flange drawn at size A, its dimensions as letters; the sizes in a table beside it flange.Update(sizes["A"]) D, d, l = 100, 30, 11 k = (D + d) / 2 hole = flange.Location("hole.center")[:2] view = View([(flange, {})], circles=[((0, 0), k / 2, "pitch"), ((0, 0), d / 2, "lines")] + [(c, l / 2, "lines") for c in [flange.Location(h + ".center")[:2] for h in ("hole", "holes.1.hole", "holes.2.hole", "holes.3.hole")]], diameters=[((0, 0), D / 2, (90, "across", -62), "D"), ((0, 0), d / 2, 135, "d"), ((0, 0), k / 2, 45, "k"), (hole, l / 2, (300, "leader", "n", "EQS"), "l")], axes=[((-56, 0), (56, 0), (0, 0)), ((0, -56), (0, 56), (0, 0))]) data = Table([("Size", "D", "d", "k", "n", "l")] + [(name, s["D"], s["d"], (s["D"] + s["d"]) / 2, s["holes.count"], s["l"]) for name, s in sizes.items()], at=(70, 14), widths=(16, 14, 14, 14, 10, 14)) drawing = SheetFigure([view, data], margin=16, notes=("planex2d.org", "2D exercise 21"), sheet=LANDSCAPE) print("scale", drawing.planex_scale, "| paper", [round(v * 25.4) for v in drawing.get_size_inches()], "mm") save_figure(drawing, "flange-series", dpi=200) plt.close(drawing) ```