• Models
  • Contests
  • Slicer
  • Login
  • Start Here
    thingiverse-iconprintables-iconcults3d-iconmakerworld-iconmyminifactory-icon

    3D GO

    3D ModelsContestsCollectionsSaved ModelsOn a mobile device?

3D GO

Privacy Policy
modRuler 3D Printer File Image 1
modRuler 3D Printer File Image 2
modRuler 3D Printer File Image 3
modRuler 3D Printer File Image 4
modRuler 3D Printer File Image 5
modRuler 3D Printer File Thumbnail 1
modRuler 3D Printer File Thumbnail 2
modRuler 3D Printer File Thumbnail 3
modRuler 3D Printer File Thumbnail 4
modRuler 3D Printer File Thumbnail 5

modRuler

jamesgt avatarjamesgt

January 27, 2023

printables-icon
DescriptionCommentsTags

Description

Concept

A dead simple, but fully modular system to build an infinite ruler, a 3 axis ruler, a center finder or maybe a space station some time.

TLDR

Print the starter kit (a folder on the files tab) to get the concept. Just open your eyes big to see the small bumper in the hole :)

Background

The current (initial version) is created in a few hours and I post it now to enter in the measurement devices contest, but my plan is to improve it with time, so please print, comment, remix and set a reminder in your calendar to look back every month.

Design

With the help of the wonderful JSCAD web version and in a hundred lines of code the base concept is now kinda ready.

You can easily try it out, just copy the following code, set up a different module order and then export it.

Modules
NameCharcodeDescriptionPreview
ConnectorC6 holes to connect them all
FullFspacer to make it loooong
PlugPthe simplest 90° thread
HoleHA hole in the middle to fit an IKEA pencil
Examples

C,F*3,P is the light blue guy on the cover photo. You can read it as: connector, then 3 pieces of full and a plug at the end.

I've tried out it as a crazy color change print, just for fun, but I don't recommend it for now until the whole project is cleaned up.

C,F,H,F,C is the center finder.

Code

Please don't review it too strict, this is a PoC created in a few hours (at very-very late).

const {
  primitives: { circle, cube, cuboid, cylinder, roundedCuboid, sphere, torus },
  transforms: { translate, mirrorX, rotate },
  booleans: { union, subtract },
  hulls: { hull, hullChain },
  text: { vectorText },
  colors: { colorize, colorNameToRgb, hexToRgb },
  extrusions: { extrudeLinear, extrudeRotate },
} = require('@jscad/modeling')

const paint = (color, elem) => colorize(colorNameToRgb(color), elem)
const side = 10
const bumperRadius = 1

const plug = (opts) => {
  const height = side / 2 - 2
  const plug = cylinder({ radius: side / 4, height, ...opts.resolution })
  const bumper = sphere({ radius: bumperRadius, ...opts.resolution })
  const bumperCoords = { x: 0, y: side / 4, z: side / 2 - bumperRadius - (side / 4 - 2 * bumperRadius) / 2 }

  const y = (height - 10) / 2
  return [
    translate([0, 0, -5 + height / 2], subtract(
      plug,
      union(
        translate([0, side / 4, 0], bumper),
        extrudeRotate({ ...opts.resolution, angle: Math.PI / 2 }, circle({ size: bumperRadius, center: [side / 4, 0] })),
        translate([side / 4, 0, 0], bumper),
        translate([side / 4, 0, height / 4], cylinder({ radius: bumperRadius, height: height / 2, ...opts.resolution })),
      ),
    )),
  ]
}

const connector = (opts) => {
  const base = cuboid({ size: [side, side, side] })
  const hole = cylinder({ radius: side / 4, height: side, ...opts.resolution })
  const bumper = sphere({ radius: bumperRadius, ...opts.resolution })
  const bumperCoords = { x: 0, y: side / 4, z: side / 2 - bumperRadius - (side / 4 - 2 * bumperRadius) / 2 }
  return [
    paint('orange', subtract(
      base,
      union(
        hole,
        rotate([Math.PI / 2, 0, 0], hole),
        rotate([0, Math.PI / 2, 0], hole),
      )
    )),
    paint('brown', union(
      translate([bumperCoords.x, bumperCoords.y, bumperCoords.z], bumper),
      translate([bumperCoords.x, bumperCoords.y, -bumperCoords.z], bumper),
      translate([bumperCoords.x, bumperCoords.z, -bumperCoords.y], bumper),
      translate([bumperCoords.x, -bumperCoords.z, -bumperCoords.y], bumper),
      translate([bumperCoords.z, bumperCoords.x, -bumperCoords.y], bumper),
      translate([-bumperCoords.z, bumperCoords.x, -bumperCoords.y], bumper),
    ))
  ]
}

const centerFinder = (opts) => {
  return [
    subtract(
      cube({size: side}),
      rotate([0, Math.PI / 2, 0], cylinder({radius: 7.5 / 2, height: side, ...opts.resolution})),
    ),
  ]
}

const mark = (elem, height, padding = 0, margin = 0.5, width = 0.2) => {
  const length = 5 - margin - padding / 2
  const line = cuboid({ size: [length, width, width] })
  const line1 = translate([5 - margin - length / 2, -5 + width / 2, height], line)
  const line2 = translate([-(5 - margin - length / 2), -5 + width / 2, height], line)
  const lines = union(line1, line2)
  return subtract(
    elem,
    union(
      lines,
      rotate([0, 0, Math.PI / 2], lines),
      rotate([0, 0, -Math.PI / 2], lines),
      rotate([0, 0, Math.PI], lines),
    ),
  )
}

const main = (params) => {
  const opts = { params, resolution: { segments: params.hires ? 32 : 16 } }
  return [union(
    params.setup.split(',')
      .map((elem) => elem.trim())
      .flatMap((elem) => {
        switch (elem.charAt(0)) {
          case 'C': return [connector(opts)]
          case 'F': return Array.from({ length: elem.length === 1 ? 1 : parseInt(elem.substring(2)) }).map(() => cube({ size: side }))
          case 'P': return [plug(opts)]
          case 'H': return [centerFinder(opts)]
          default: return []
        }
      })
      .map((elem) => union(elem))
      .map((elem) => params.marks ? mark(elem, side / 10 * 5) : elem) // mark at top
      .map((elem) => params.marks ? mark(elem, side / 10 * 4, 6) : elem)
      .map((elem) => params.marks ? mark(elem, side / 10 * 3, 6) : elem)
      .map((elem) => params.marks ? mark(elem, side / 10 * 2, 6) : elem)
      .map((elem) => params.marks ? mark(elem, side / 10 * 1, 6) : elem)
      .map((elem) => params.marks ? mark(elem, 0, 2) : elem) // params.marks ? mark at center
      .map((elem) => params.marks ? mark(elem, -side / 10 * 1, 6) : elem)
      .map((elem) => params.marks ? mark(elem, -side / 10 * 2, 6) : elem)
      .map((elem) => params.marks ? mark(elem, -side / 10 * 3, 6) : elem)
      .map((elem) => params.marks ? mark(elem, -side / 10 * 4, 6) : elem)
      .map((elem) => params.marks ? mark(elem, -side / 10 * 5) : elem) // mark at bottom
      .map((elem, i) => translate([0, 0, i * side], elem))
  )]
}

const getParameterDefinitions = () => [
  { name: 'hires', type: 'checkbox', checked: true, initial: 0, caption: 'high resolution' },
  { name: 'setup', type: 'text', caption: 'setup', placeholder: 'C,F,H,F,P' },
  { name: 'marks', type: 'checkbox', checked: true, initial: 0, caption: 'marks' },
]

module.exports = { main, getParameterDefinitions }

Remarks

You might want to set high resolution for the export, but turn it of when you just tweak the settings or the code as it gets slow pretty quick.

There are issues with the generated model, but looks like that “Fix through the Netfabb” option of the Prusa Slicer get rid all of them.

License:

Creative Commons — Attribution — Noncommercial — Share Alike

Related Models

Thor Mjolnir Hammer Bic Pen preview image

Thor Mjolnir Hammer Bic Pen

effektz profile image

effektz

9,094

Diverse Schilder / various labels  for hobby & makers preview image

Diverse Schilder / various labels for hobby & makers

RPK profile image

RPK

2

Cute Fluffy Puppy Figurine to Print preview image

Cute Fluffy Puppy Figurine to Print

bonowski. profile image

bonowski.

3

Vorpal The Hexapod Walking Robot preview image

Vorpal The Hexapod Walking Robot

vorpal profile image

vorpal

4,986

MakerZ – Open Source 1/28 RC Drift Chassis by Fails & Makes | Açık Kaynak 1/28 RC Drift Şasisi preview image

MakerZ – Open Source 1/28 RC Drift Chassis by Fails & Makes | Açık Kaynak 1/28 RC Drift Şasisi

Fails&Makes profile image

Fails&Makes

Customizable EU License Plate Keychain preview image

Customizable EU License Plate Keychain

John_M profile image

John_M

43

Snap-Together Mini Minecraft Jack-O-Lantern with integrated LED preview image

Snap-Together Mini Minecraft Jack-O-Lantern with integrated LED

scottrlindsey profile image

scottrlindsey

4,456

Small Parts Storage Drawers - Organizer preview image

Small Parts Storage Drawers - Organizer

GT 3D Makers profile image

GT 3D Makers

29

9