Gear pump gasket
A gear pump moves oil between two meshing gears that turn in two chambers of its housing, so the housing’s opening is two overlapping circles, and the gasket that seals its cover follows that figure eight. The gasket’s outline and the line of its bolt holes keep their distance from the opening all around, since they are offsets of it. The holes are spaced equally along the bolt line, a pattern along a curve rather than on a circle. Model the gasket from the drawing in planex2d or in any CAD system, then check its area against the value at the end of the page. A solution in planex2d follows.

[1]:
import math
import planex as px
The opening
The rotors are two gears of module 2 with 17 teeth, 38 across their tips, and their centers are 34 apart, their pitch diameter. Each chamber is a circle of 38.5 around a gear’s center, a radial clearance of 0.25, on the \(x\) axis 17 to either side of the origin. px.Unify unites the two discs into the figure eight, with two corners where the circles cross (Figure 1):
[3]:
opening = px.Unify([px.Circle((-17, 0), 38.5 / 2).Face(), px.Circle((17, 0), 38.5 / 2).Face()]).Face()
print("corners", [(round(v.x, 4), round(v.y, 4)) for v in opening.vertices])
corners [(0.0, 9.0312), (0.0, -9.0312)]
(a) The two chambers
(b) United: the opening
The outline and the bolt line
The gasket reaches 16 beyond the opening all around, and the bolt holes lie on a line 8 beyond it, in the middle of the gasket’s width. Both are offsets of the opening’s face, outward. An offset of a face is a shape, here of one face. Face() takes that face, and its outer wire is the bolt line (Figure 2):
[5]:
outline = opening.Offset(16, inplace=False).Face() # a copy, 16 outward
bolt_line = opening.Offset(8, inplace=False).Face().outer
print("bolt line", len(bolt_line.edges), "arcs,", round(bolt_line.mass, 4), "long")
bolt line 2 arcs, 244.6461 long
The holes
The ten holes of 6.6 lie equally spaced along the bolt line, one pitch of its length apart, the first half a pitch from the corner where the bolt line starts. PointAt gives the point at a fraction of an edge’s length, so walking along the bolt line’s two arcs gives each hole’s center (Figure 3):
[7]:
pitch = bolt_line.mass / 10
targets = [pitch / 2 + k * pitch for k in range(10)]
centers, walked = [], 0.0
for e in bolt_line.edges:
length = e.Measure()["length"]
for t in targets:
if walked <= t < walked + length:
p = e.PointAt((t - walked) / length) # the point at that fraction of the edge's length
centers.append((p.x, p.y))
walked += length
gasket = outline - opening
for c in centers:
gasket = gasket - px.Circle(c, 6.6 / 2).Face()
gasket = gasket.Face()
print("pitch", round(pitch, 4))
pitch 24.4646
The checks
This is the area, to compare with your own model. Offsetting the union of two discs outward gives the union of the larger discs, so the outline is the union of two circles of 35.25 around the same centers. Two circles of radius \(r\) whose centers are \(d\) apart overlap in a lens of \(2 r^2 \arccos\left(\tfrac{d}{2r}\right) - \tfrac{d}{2} \sqrt{4 r^2 - d^2}\), and their union is \(2 \pi r^2\) less the lens. The gasket is the outline’s union less the opening’s and the ten holes. It is symmetric about both axes, so its centroid is the origin (Figure 4):
[9]:
def union(r, d=34):
return 2 * math.pi * r**2 - (2 * r**2 * math.acos(d / (2 * r)) - d / 2 * math.sqrt(4 * r**2 - d**2))
exact = union(35.25) - union(19.25) - 10 * math.pi * 3.3**2
print("area", round(gasket.mass, 4), "mm², exact", round(exact, 4))
print("centroid", tuple(round(v, 6) for v in gasket.center[:2]))
area 3588.5835 mm², exact 3588.5835
centroid (0.0, -0.0)
The gasket as DXF in millimeters, for a cutting plotter or a laser cutter:
[11]:
gasket.WriteDXF("pump_gasket.dxf", unit=px.mm, scale=1) # scale=1: the numbers as they are
The gasket as DXF: pump_gasket.dxf