I meant to update this thread with progress on my headboard, but forgot to do so. I'd got to the point where I could generate a headboard but the letter spacing was causing me a headache:
SimonWood wrote: ↑Sat Jan 01, 2022 9:14 am
Even after fiddling the parameters you can see the letter spacing is a problem more generally - since really having each letter spaced evenly never works. An 'I' is much narrower than a 'W'. I haven't found anything in OpenSCAD to solve this, although I think from Googling around there may be libraries other people have developed which I can use - I need to look into this more...
Well, I found the library to do this, and in the process I also found a new OpenSCAD command which I think is going to be really useful for structuring projects.
The library is
fontmetrics which includes the function measureText() which returns the width of a string - exactly what I needed! So I can now measure the width of each letter individually and use that to work out the angle to move through before position the next letter. Job done!
Code: Select all
function angle_subtended_by_arc(radius,arc_length) = arc_length*360/(2*radius*PI);
function add_elements(array, to=-1, from=0) = from < len(array) - 1 && (from < to || to == -1) ? array[from] + add_elements(array, to, from + 1) : array[from];
function angles_of_letters(the_text,radius,font_size) = [for (i=[0:len(the_text)-1]) angle_subtended_by_arc(radius,measureText(the_text[i],size=font_size))];
module text_arc(the_text,radius,font_size,center=false) {
angles_of_letters=angles_of_letters(the_text,radius,font_size);
center_offset = center ? add_elements(angles_of_letters,len(the_text)-1)/2 : 0;
for (i = [0:len(the_text)-1]) {
rotate(i == 0 ? center_offset : center_offset-add_elements(angles_of_letters,i-1))
translate([0,radius,0])
text(the_text[i],halign="left",font_size);
}
}
But that code won't work yet, because the function measureText() isn't defined in my project, it's in fontmetrics.scad. So first of all I need to download fontmetrics (and its companion fontmetricsdata.scad) and I can then either place it in the same directory (folder) as my project, or in one of the places OpenSCAD looks for libraries - I won't cover the details of that here because it depends which operating system you're on, but it's an option if you think that's neater. Once I've done that, I have to include a line in my project to reference fontmetrics. There are actually two OpenSCAD commands that can do this: include<> and use<>. If you include<file.scad>; it basically pulls in everything in file.scad as if it were in your file. But if you use<file.scad>; it only brings in the modules and functions from file.scad so you can call them from with your project. I prefer this: it means if I define a constant in my project that happens to share the same name as a constant in the file I want to reference, it won't cause a clash.
Anyway, having added fontmetrics.scad to the same folder as headboard.scad, all I need to do now is add this line:
Now my function above will be able to use measureText().
The benefit of this command is that I can now break down my projects into multiple files. So if I were drawing a wagon I could, say, have files axlebox.scad and solebar.scad and coupling.scad etc. and then in reference them in wagon.scad with 'use<axlebox.scad>;' etc. Not only will this make it more organised to work on and easier to find the bits of code I'm looking for, but potentially I can reuse bits (for example I might want to use 'axlebox.scad' in 'van.scad'). Admittedly this also increases the potential for complexity... and this has made me think about versioning. I'm experimenting with using GitHub for this - so you can now find the latest working
headboard files on GitHub.
I've also finally got round to putting the
headboard project on Thingiverse.
So even if you don't want to play with the OpenSCAD code you can now download it and type your own headboard text in as a parameter to generate an STL file for any headboard you like.