RoseEngine
Documentation for RoseEngine.
I first learned abot rose engines from the ClixkSpring YouTube channel. Other information and inspiration came from the channels of Uri Tuckman and DM Tiffany Timepieces.
A rose engine is similar to a lathe but has cams on the spindle which can control the position of the cross slide and thus the radius of the cutter from the axis of the spindle.
This can be modeled by a function that maps a parametric angle - the rotation of the spindle - to the radius of the cutter from the spindle's axis. This function is implemented by the Rotor struct.
Because each of the cams on a rose engine has an integer number of lobes, the rose engine also has a way to offset the cam from the axis of rotation by an initial phase angle. A rose engine also has a way to add an initial phase angle to the axis of rotation. We model this using PhasedRotor.
Wave Functions
Rotor expects a wave functioon. These are the available wave functions
RoseEngine.triangle_wave — Function
triangle_wave(p)triangle_wave implements a symetric triangle wave suitable for use as the wave_function of Rotor.
RoseEngine.sine_wave — Function
sine_wave(a)sine_wave implements a sine wave suitable for use as the wave_function of Rotor.
Writing an SVG File
A real rose engine is a continuous, analog machine. On a digital computer we can only use discreet steps. To generate our pattern we use a sequence of discreet steps at which we compute the position of the cutter. This step size is specified by a step_angle parameter. The graphic is generated starting with a step_angle of 0 and incrementing it by step_angle until the cutter returns to its starting position. This is performed by svg_path_for_rotor.
My CNC router (Shaper Origin) is driven by an SVG file. Here's how I can write one from this package:
using RoseEngine
rotor = Rotor(3, 1//2, 1//8, sine_wave)
render_rotors(joinpath(@__DIR__, "svg-example-1.svg"),
map([ 0, 1//32, 2//32, 3//32 ]) do phase
PhasedRotor(rotor, phase)
end,
1//256)falseHere's the resulting file:
using RoseEngine
rotor = Rotor(3, 1, 13//29, sine_wave)
render_rotors(joinpath(@__DIR__, "svg-example-2.svg"),
rotor,
1//256)falseusing RoseEngine
rotor = Rotor(3, 1, 43//5, triangle_wave)
render_rotors(joinpath(@__DIR__, "svg-example-3.svg"),
rotor,
1//256)falseIndex
RoseEngine.PhasedRotorRoseEngine.RotorRoseEngine.full_cycle_countRoseEngine.input_rangeRoseEngine.sine_waveRoseEngine.sine_waveRoseEngine.svg_path_for_rotorRoseEngine.triangle_waveRoseEngine.triangle_wave
Other Definitions
RoseEngine.PhasedRotor — Type
PhasedRotor(::Rotor, initial_phase_angle)PhasedRotor encapsulates a Rotor to provide an initial phase angle offset when drawing the rotor.
RoseEngine.Rotor — Type
Rotor(radius, amplitude, waves_per_rotation)Rotor is a function that for a given angle, returns a radius from the center of the Rotor's spindle. In this package, angles are in units of fractions of a full circle, arther than in degrees or radians.
radius is the radius at zero amplitude.
amplitude is the extent above and below radius of the range of the "cutter". The range of the Rotor funnction will be from radius - amplitude to radius + amplitude.
wave_function is a function describing one cycle of the wave. Its domain goes from 0 to 1 and its range goes from -1 to 1. See [triangle_wave(@ref) as an example.
waves_per_rotation is the number of full oscillations of wave_function per one turn of the Rotor.
RoseEngine.full_cycle_count — Method
full_cycle_count(::AbstractRotor)::IntReturns the number of cycles that the Rotor should rotate such that its wave_function returns to its starting point (same angle and radius). This is an integer number of full rotations of the rootor.
RoseEngine.input_range — Method
input_range(::AbstractRotor, step_angle::Rational)Returns a Julia AbstractRange that will fully generate the design of the Rotor when the rotor function is applied to the values of that range.
RoseEngine.sine_wave — Method
sine_wave(a)sine_wave implements a sine wave suitable for use as the wave_function of Rotor.
RoseEngine.svg_path_for_rotor — Method
svg_path_for_rotor(rotor::Rotor, step_angle::Rational)Returns an SVG path expression suitable for the value of the d attribute of an SVG path to draw the design specified by the Rotor. Also returns the minimum and maximum x and y coordinates of the path.
RoseEngine.triangle_wave — Method
triangle_wave(p)triangle_wave implements a symetric triangle wave suitable for use as the wave_function of Rotor.