From 1054fe8498db93a6e9a194e83b80acb556e8b5c4 Mon Sep 17 00:00:00 2001 From: Sam Ettinger Date: Sat, 1 Apr 2023 00:21:44 -0700 Subject: [PATCH] Good updates --- README.md | 43 +++++++++++++++++++++++-------- lowercase.txt | 8 +++--- selectric_generator.py | 58 ++++++++++++++++++++++++++++++++++++++---- uppercase.txt | 8 +++--- 4 files changed, 93 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index f293a6f..78d4c61 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,8 @@ # this may get pretty complex fast, and i won't have time to improve the documentation for a while sorry everyone +# Remind me to put some of these up for sale through Shapeways, for folks who don't want to print them themeslves! + The [IBM Selectric typewriter](https://www.ibm.com/ibm/history/ibm100/us/en/icons/selectric/) uses an instantly-recognizable "ball" of type instead of a fanned-out array of arms like a conventional typewriter. These typeballs could be swapped out, meaning you could easily write documents with different fonts, font sizes, special characters, or different writing systems altogether. IBM and some other vendors made lots of different typeballs, but most of them are 40-50 years old and no one has been making new typeballs for a long time. 3D printing is a natural fit for making new typeballs, but most printers still don't have the ability to produce the sharp details necessary on a sufficiently-resilient material. So it's understandable that no one tried to make a really polished 3D-printable typeball. Until now, that is! @@ -16,7 +18,21 @@ Things you need before getting started: 1. Open `oneletter.scad` and change lines 10 and 11, the ones that specify the font height (in millimeters) and the font name/style for OpenSCAD to use. 1. Open `selectric_generator.py` and change line 5, the one that says `PATH TO OPENSCAD = r"{something}"` so that it points to your installation of `openscad.com` (not `openscad.exe`! They are in the same folder probably, but the `.com` is meant to be run from command line, which is what we'll be doing. -1. If you want to change the keyboard layout, edit `uppercase.txt` and `lowercase.txt`. Right now the way they are set up is a little...strange. I need to adjust that, I have some ideas! +1. If you want to change the keyboard layout, edit `uppercase.txt` and `lowercase.txt`. Each .txt file has four rows, representing the characters in order on the Selectric keyboard. For example, for a standard QWERTY keyboard layout the files should look like: +``` +uppercase.txt +!@#$%¢&*()_+ +QWERTYUIOP¼ +ASDFGHJKL:" +ZXCVBNM,.? +``` +``` +lowercase.txt +1234567890-= +qwertyuiop½ +asdfghjkl;' +zxcvbnm,./ +``` 1. Run `selectric_generator.py`. On my machine, each character takes between 1 and 30 seconds to generate, depending on their complexity. So 88 characters will take a while, be patient! ## Some extra things @@ -26,16 +42,21 @@ The blank typeball is based on [1944GPW's typeball on Thingiverse](https://www.t To make a typeball that sticks close-ish to the standard Cherokee keyboard layout: ``` uppercase.txt -ᎱᏧᏡᎺᎰᏃᏇᎹᏝᏤᎶ -ᏭᎭᏐᏟᎮᏘᎻᏣᎧᎲᏰ -ᎷᏞᏏᏌᏬᏑᎴᏀᏱᏎᏫ -ᏥᏈᏠᏢᏉᎫᎽᏆᏪᏲᎼ +ᎱᏇᏧᎰᎹᏝᏡᎺᎶᏤᎼᎽ +ᏆᏫᏣᏏᏘᏲᎭᏱᏬᏪᏑ +ᏌᏎᏐᏈᏥᎲᎫᎧᎮᏠᏀ +ᏃᏭᏟᏞᏰᎻᎷᏢᎴᏉ ``` - ``` lowercase.txt -ᏊᏩᏋᏖᏙᎬᏮᏦᏜᏄᏒ -ᏴᎤᏗᏓᎵᏔᎾᎡᎸᎯᎨ -ᏅᎥᏛᎠᎣᏕ.'ᎢᏍᎳ -ᎦᎩᏨ,ᏂᏚᏳᎪᏁᏯᎿ -``` \ No newline at end of file +ᏊᏮᏩᏙᏦᏜᏋᏖᏒᏄᎿᏳ +ᎪᎳᎡᏛᏔᏯᎤᎢᎣᏁᏕ +ᎠᏍᏗᎩᎦᎯᏚᎸᎵᏨ' +ᎬᏴᏓᎥᎨᎾᏅ,.Ꮒ +``` + +How do you set the horizontal spacing between keypresses on a Selectric? There's got to be a way, right? Knowing the exact horizontal advance between keystrokes is critical if I'm going to get a Mongolian typeball to work. That would also require me to acquire a right-to-left writing typewriter; can all Selectrics change writing direction? + +Other right-to-left scripts to try: Thaana, N'ko + +Other typeballs to try: Osage, Tifinagh, various runes, emoji, Avoiuli, um......what else? \ No newline at end of file diff --git a/lowercase.txt b/lowercase.txt index 0c1b0ed..d61e53b 100644 --- a/lowercase.txt +++ b/lowercase.txt @@ -1,4 +1,4 @@ -13784z25609 -xudcltnekhb -mvrao½.'isw -gf;,/j=qpy- \ No newline at end of file +1234567890-= +qwertyuiop½ +asdfghjkl;' +zxcvbnm,./ \ No newline at end of file diff --git a/selectric_generator.py b/selectric_generator.py index f08c470..bec5c25 100644 --- a/selectric_generator.py +++ b/selectric_generator.py @@ -10,15 +10,63 @@ glyphs = [] with open("uppercase.txt", "r", encoding="utf-8") as uppercaseText: - for row, line in enumerate(uppercaseText.readlines()[0:4]): - for column, glyph in enumerate(line.strip()[0:11]): + rows = uppercaseText.readlines()[0:4] + rows = [x.strip("\r\n") for x in rows] + if len(rows[0]) != 12: + print("First keyboard row should have 12 characters!") + raise + elif len(rows[1]) != 11: + print("Second keyboard row should have 11 characters!") + raise + elif len(rows[2]) != 11: + print("Third keyboard row should have 11 characters!") + raise + elif len(rows[3]) != 10: + print("Fourth keyboard row should have 10 characters!") + + a = rows[0] + b = rows[1] + c = rows[2] + d = rows[3] + + ballOrder = [a[0]+a[2]+a[6]+a[7]+a[3]+d[0]+a[1]+a[4]+a[5]+a[9]+a[8], + d[1]+b[6]+c[2]+d[2]+c[8]+b[4]+d[5]+b[2]+c[7]+c[5]+d[4], + d[6]+d[3]+b[3]+c[0]+b[8]+b[10]+d[8]+c[10]+b[7]+c[1]+b[1], + c[4]+c[3]+c[9]+d[7]+d[9]+c[6]+a[11]+b[0]+b[9]+b[5]+a[10]] + + for row, line in enumerate(ballOrder): + for column, glyph in enumerate(line): glyphs += [(row, column, 1, glyph)] with open("lowercase.txt", "r", encoding="utf-8") as lowercaseText: - for row, line in enumerate(lowercaseText.readlines()[0:4]): - for column, glyph in enumerate(line.strip()[0:11]): - glyphs += [(row, column, 0, glyph)] + rows = lowercaseText.readlines()[0:4] + rows = [x.strip("\r\n") for x in rows] + if len(rows[0]) != 12: + print("First keyboard row should have 12 characters!") + raise + elif len(rows[1]) != 11: + print("Second keyboard row should have 11 characters!") + raise + elif len(rows[2]) != 11: + print("Third keyboard row should have 11 characters!") + raise + elif len(rows[3]) != 10: + print("Fourth keyboard row should have 10 characters!") + a = rows[0] + b = rows[1] + c = rows[2] + d = rows[3] + + ballOrder = [a[0]+a[2]+a[6]+a[7]+a[3]+d[0]+a[1]+a[4]+a[5]+a[9]+a[8], + d[1]+b[6]+c[2]+d[2]+c[8]+b[4]+d[5]+b[2]+c[7]+c[5]+d[4], + d[6]+d[3]+b[3]+c[0]+b[8]+b[10]+d[8]+c[10]+b[7]+c[1]+b[1], + c[4]+c[3]+c[9]+d[7]+d[9]+c[6]+a[11]+b[0]+b[9]+b[5]+a[10]] + + for row, line in enumerate(ballOrder): + for column, glyph in enumerate(line): + glyphs += [(row, column, 0, glyph)] + # Define some values we'll use throughout this # Letters extend out 0.6875" from the center of the typeball # The ball itself has a radius of around 0.6625" diff --git a/uppercase.txt b/uppercase.txt index c0b9400..da615de 100644 --- a/uppercase.txt +++ b/uppercase.txt @@ -1,4 +1,4 @@ -!#&*$Z@%¢)( -XUDCLTNEKHB -MVRAO¼."ISW -GF:,?J+QPY_ \ No newline at end of file +!@#$%¢&*()_+ +QWERTYUIOP¼ +ASDFGHJKL:" +ZXCVBNM,.? \ No newline at end of file