--- jupyter: description: 'A split shaft collar as a 3D CAD exercise: a dimensioned drawing with a section through its middle plane to model in planex2d or any CAD system, a solution from a ring padded, a slit pocketed through one side, and the clamp screw''s counterbore, clearance hole and tapped hole sketched on planes parallel to the slit, and the volume, mass and center of mass to check a model against.' --- # Split shaft collar A shaft collar sits on a shaft as a stop and locates a bearing, a gear or a lever along it. A one-piece clamp collar is a ring with a slit through one side, and a screw across the slit pulls its two sides together, so that the ring closes on the shaft. The screw's holes are square to the slit, away from the axis, where neither the ring's faces nor its round outside give them a plane. They are sketched on planes of their own, set by their distance from the axis. Model the collar from the drawing in planex2d or in any CAD system, then check its volume, mass and center of mass against the values at the end of the page. A solution in planex2d follows. ![The split shaft collar exercise: a dimensioned drawing of a ring with a slit and a clamp screw's holes across it, in a section through its middle plane, a view onto the screw's counterbore and an isometric](../_static/gallery/shaft-collar.png){.result} ```python import math import netgen.occ as occ import planex as px ``` ```python nbsphinx="hidden" from docs_figures import Row, Views ``` ## The ring The ring is sketched on the xy plane, its axis the $z$ axis, as the outside of 40 and the bore of 20, concentric around the origin. `px.Pad` extrudes it 12 up, the collar's width (Figure 1): ```python ring = px.Sketch(auto_constraint=True) ring.Circle(40 / 2, id="outside") ring.Circle(20 / 2, concentric="outside", id="bore") ring.Constrain("outside.center", "origin", px.Coincident) ring.Constrain("outside", px.Diameter, 40, id="outside_d") ring.Constrain("bore", px.Diameter, 20, id="bore_d") print("status", ring.status, "| degrees of freedom", ring.dof) collar = px.Pad(ring, 12) ``` ```python nbsphinx="hide-input" Row((ring, "The ring, every dimension and tie", {"constraints": True}), (collar, "Padded 12", {"views": [(collar, "shade"), (collar, "ink")], "angles": (-60, 0, 30)}), caption="The ring") ``` ## The slit The slit is 1.5 wide, through the ring's wall on the side of $+y$, its middle plane the plane $x = 0$. It is a `RectangleC` on the ring's top, 1.5 across and 20 along the $y$ axis, longer than the wall, its center on the vertical axis 15 out. It overhangs the wall on both sides, so it is pocketed by the ring's width, 12 deep (Figure 2): ```python slit = px.Sketch(collar.faces.Max(occ.Z), auto_constraint=True) # on the top face: h along x, v along y slit.RectangleC((0, 15), 1.5, 20, id="slit") # 1.5 along x, 20 along y, around its center slit.Constrain("slit.center", "V", px.Coincident) slit.Constrain("slit.center", "H", px.Distance, 15, id="slit_at") slit.Constrain("slit.Line.1", px.Horizontal) # the rectangle does not turn slit.Constrain("slit.Line.1", px.Distance, 1.5, id="slit_w") slit.Constrain("slit.Line.2", px.Distance, 20, id="slit_l") print("status", slit.status, "| degrees of freedom", slit.dof) collar = px.Pocket(collar, slit, 12) ``` ```python nbsphinx="hide-input" Views(("The slit through the wall", [(collar, "shade"), (collar, "ink")]), angles=(-30, 0, 30), caption="The slit") ``` ## The clamp screw's holes The screw, M5, runs along $x$ across the slit, 15 from the axis and in the middle of the width, 6 up. Its head sits in a counterbore of 9.5 on the side of $+x$, and its thread goes into a tapped hole on the other side. The planes square to the screw are the yz plane, $x = 0$, which is the slit's middle plane, and its parallels. `px.Plane(px.YZ, 20)` is the plane $x = 20$, outside the ring, its $h$ along $y$ and its $v$ along $z$. The counterbore is sketched on that plane and pocketed 11 deep against its normal, toward the slit, so that the screw head's seat lies 9 from the slit's middle plane. It cuts through the round outside and leaves a flat seat for the head (Figure 3): ```python counterbore = px.Sketch(px.Plane(px.YZ, 20)) # the plane x = 20: h along y, v along z counterbore.Circle(9.5 / 2, center=(14, 5), id="counterbore") counterbore.Constrain("counterbore.center", "V", px.Distance, 15, id="screw_at") counterbore.Constrain("counterbore.center", "H", px.Distance, 6, id="screw_z") counterbore.Constrain("counterbore", px.Diameter, 9.5, id="counterbore_d") print("status", counterbore.status, "| degrees of freedom", counterbore.dof) collar = px.Pocket(collar, counterbore, 11) ``` ```python nbsphinx="hide-input" Row((counterbore, "The counterbore on the plane x = 20, the collar behind", {"plot": {"show_parent": collar, "show_constraints": True}}), (collar, "The counterbore through the outside", {"views": [(collar, "shade"), (collar, "ink")], "angles": (-30, 0, 60)}), caption="The counterbore") ``` The clearance hole of 5.5 is sketched on the same plane around the counterbore's solved center and pocketed 20 deep, to the slit's middle plane. The tapped hole, the tapping drill of 4.2 for the M5 thread, 12 deep, is sketched on the slit's middle plane, the yz plane, around the screw's axis, and pocketed against its normal, away from the head (Figure 4): ```python axis = counterbore.Location("counterbore.center") # the screw's axis, in the planes' coordinates clearance = px.Sketch(px.Plane(px.YZ, 20)) clearance.Circle(5.5 / 2, center=axis, id="clearance") clearance.Constrain("clearance", px.Diameter, 5.5, id="clearance_d") collar = px.Pocket(collar, clearance, 20) tapped = px.Sketch(px.YZ) tapped.Circle(4.2 / 2, center=axis, id="tapped") tapped.Constrain("tapped", px.Diameter, 4.2, id="tapped_d") collar = px.Pocket(collar, tapped, 12) ``` ```python nbsphinx="hide-input" Views(("The clearance hole and, across the slit, the tapped hole", [(collar, "shade"), (collar, "ink")]), angles=(-120, 0, 60), caption="The screw's holes") ``` ## The checks These are the volume, the mass in steel C45 (7.85 g/cm³) and the center of mass, with the origin on the axis at the bottom, to compare with your own model. The collar is symmetric about its middle plane $z = 6$, so its center of mass lies in it. The slit and the holes take material on the side of $+y$, so it lies off the axis toward $-y$, and the counterbore and the holes along $x$ move it a little toward $-x$: ```python c = collar.center print("volume", round(collar.mass, 1), "mm³") print("mass", round(collar.mass * 7.85e-6, 4), "kg") print("center of mass", (round(c.x, 4), round(c.y, 4)), "| off the middle plane by", round(abs(c.z - 6), 6)) ``` The collar as STEP, for another CAD system: ```python collar.WriteStep("shaft_collar.step") ``` The collar as STEP: [shaft_collar.step](shaft_collar.step) ```python nbsphinx="hidden" import sys sys.path.insert(0, "..") import matplotlib.pyplot as plt from drawings import Pictorial, SheetFigure, View from gallery import save_figure # first angle: the plan as a section through the middle plane z = 6 (the symmetry plane of the width: no designation # needed), the part below it seen from above, its cut faces hatched; the view from the right onto the counterbore, # to the left of the plan; the slit's width and the screw's place in the plan below = collar * occ.Box((-25, -25, -1), (25, 25, 6)) cut = [f for f in below.faces if abs(f.center.z - 6) < 1e-6 and f.bounding_box[1].z - f.bounding_box[0].z < 1e-6] plan = View([(ring, {"outside_d": 315, "bore_d": 225})], solid=below, plane=px.XY, hidden_edges=False, hatch=cut, axes=[((-24, 0), (24, 0)), ((0, -24), (0, 34)), ((-16, 15), (24, 15))], # the screw's holes from the slit's middle plane, as a chain along one line; the thread by its size measures=[((-0.75, 20), (0.75, 20), 25, 1.5), ((-12, 15), (0, 15), 31, 12), ((0, 17), (9, 17), 31, 9), ((24, 0), (24, 15), 30, 15)], diameters=[((-6, 15), 2.1, (150, "leader"), "M5")]) right = px.Plane(normal=(1, 0, 0)) # the view from the right: y to the right, z up side = View([(counterbore, {"screw_z": 6, "counterbore_d": (60, "leader")}), (clearance, {"clearance_d": (300, "leader")}, {})], solid=collar, plane=right, at=(-70, 0), hidden_edges=False, axes=[((15, -3), (15, 15)), ((-24, 6), (24, 6))], measures=[((-20, 0), (-20, 12), -26, 12)]) pictorial = Pictorial(collar, at=(-70, -40), width=36, angles=(-50, 0, 120)) drawing = SheetFigure([plan, side, pictorial], margin=16, notes=("planex2d.org", "3D exercise 21"), first_angle=True) print("scale", drawing.planex_scale, "| paper", [round(v * 25.4) for v in drawing.get_size_inches()], "mm") save_figure(drawing, "shaft-collar", dpi=200) plt.close(drawing) ```