Skip to main content

Cylindrical

A cylindrical mate is a revolute and a slider in one: the two connectors share their Z axis, and the second part may both rotate about it and travel along it. It is the joint of a piston in a bore, a shaft in a plain bearing, a pin in a slot.

Free motionrotation about Z, travel along Z

In the viewport

  1. Click Cylindrical on the assembly toolbar and pick the two connectors — the bore's frame first, then the piston's.
  2. The piston snaps onto the bore axis. Drag it to slide it in and out, or spin it.
  3. Offset takes a Z value only and sets the rest position along the axis — negative here, down into the bore; Rotate sets the rest angle. There are no limits on a cylindrical mate.
  4. Click Apply.

Piston half-way down its cylinder bore

The code behind it

The cylinder's connector is the top face's frame, centred on the bore mouth with Z pointing up the axis; the piston's sits on its skirt with Z pointing down, so face-to-face puts the piston upright on the axis and the negative Z offset sends it down the bore:

cylinder.part.js
cylinder.part.js
import { part, sketch, line, circle, extrude, cut, chamfer, select, connector } from 'fluidcad/core';
import { face } from 'fluidcad/filters';
import { coincident, distance, fix, horizontal, vertical } from 'fluidcad/constraints';

// A cylinder body: 40 × 40 × 50 mm block with a Ø20 bore, 40 deep, from the top.
export const cylinder = part('Cylinder body', () => {
sketch('xy', () => {
const b = line([-20, -20], [20, -20]);
const r = line([20, -20], [20, 20]);
const t = line([20, 20], [-20, 20]);
const l = line([-20, 20], [-20, -20]);
coincident(b.end(), r.start());
coincident(r.end(), t.start());
coincident(t.end(), l.start());
coincident(l.end(), b.start());
horizontal(b);
horizontal(t);
vertical(r);
vertical(l);
fix(b.start(), [-20, -20]);
distance(b.start(), b.end(), 40);
distance(r.start(), r.end(), 40);
});
const body = extrude(50);
sketch(body.endFaces(), () => {
circle([0, 0], 20);
});
const bore = cut(40);
chamfer(1, bore.startEdges());
// The bore mouth: the top face's frame, centred on the bore with Z
// pointing up the axis. A piston mated here sits on the axis; a Z
// offset sets how deep it goes.
connector('bore', select(face().planar().onPlane('xy', 50)));
});
piston.part.js
piston.part.js
import { part, sketch, circle, extrude, chamfer, color, select, connector } from 'fluidcad/core';
import { face } from 'fluidcad/filters';

// A piston: Ø19.8 × 30 body with a chamfered crown and a Ø8 × 30 rod.
export const piston = part('Piston', () => {
sketch('xy', () => {
circle([0, 0], 19.8);
});
const body = extrude(30);
chamfer(1, body.endEdges());
sketch(body.endFaces(), () => {
circle([0, 0], 8);
});
extrude(30);
color('tomato');
// The skirt: the bottom face, Z pointing down toward the bore floor.
connector('skirt', select(face().planar().onPlane('xy', 0)));
});
actuator.assembly.js
import { assembly, insert, mate } from 'fluidcad/core';
import { cylinder } from './asm-cylinder.part.js';
import { piston } from './asm-piston.part.js';

export const actuator = assembly('actuator', () => {
const body = insert(cylinder).grounded();
const ram = insert(piston).translate(0, 0, 80);

// Cylindrical = revolute + slider: the piston can spin about the bore
// axis AND travel along it. Only a Z offset is allowed, since the two
// frames share their axis — here it puts the skirt 20 mm down the bore,
// so the piston stands half in, half out.
mate('cylindrical', body.connectors.bore, ram.connectors.skirt).offset(0, 0, -20);
});

Options

mate('cylindrical', body.connectors.bore, ram.connectors.skirt)
.offset(0, 0, -20) // rest 20 down the bore (Z only)
.rotate(90) // rest angle about the axis
.flip()

.offset() with a non-zero X or Y and .limits() are refused on a cylindrical mate. When you need travel bounds, use a slider; when you need the rotation locked, a slider too; when you need the travel locked, a revolute.