I found an example on Thingiverse, a rubber band powered boat with two peddle wheels, but it has two problems. First of all the author only provides .stl files and second the design is a bit flawed. I therefore decided to design the boat from scratch with the 3d CAD program OpenSCAD. With OpenSCAD I’m not only able to edit my models quickly, I’m also able to share the OpenSCAD script allowing other to use and change it. Links to the downloadable files can be found here: https://my.hidrive.com/share/pyilt3itb8
The Paddle Wheel Boat that I created consists of four parts: the boat, the shaft and two peddles. The main change of the boat that I designed is the position of the shaft. It’s been shifted to the middle of the boat providing more balance. I also enforced the attachment point of the rubber band to the boat making it impossible to break it.
I also increased the size of the paddles enabling the boat to move faster. The shape of the paddles are rounded instead of square improving the dynamics of the paddles through the water. A problem with the old design is that the rubber band has to be fixed to the shaft with some tape. Not a very elegant solution. I added a square hole to the design of the shaft. The rubber band can be inserted through the hole and fixed to the shaft. No tape needed.
Changes to the models are easily made. The OpenSCAD script is simple and the result of a change can be reviewed immediately by pressing F5. E.g to move the shaft to the back of the boat can be achieved by just one simple change in the script.
Just four parts, the boat, shaft and two peddles, are needed to make the boat. If you don’t want to make changes to the design just download the provided .stl files and open them in your favourite slicer. After printing the Peddle wheel boat can be assembled and tested. Have fun.
Writing a script for a simple hook in OpenSCAD is easy but I wanted to do something more and make a parametric hook. With parametric I mean that a user can easily adjust the script by changing some variables to make your own hook.
To make it even easier the script makes use of the Customizer of OpenSCAD. This means that users don’t have to tinker with the code but can adjust the values of the variables with a easy to use panel on the right side of the GUI of OpenSCAD called the Customizer. (If you don’t see the Customizer in OpenSCAD go to the menu bar and click on Windows and then Customizer).
Aside from changing the dimensions I also added the possibility to add a fillet or a chamfer to the hook. And I added the option to change the radius of the hook and the diameter of the screw holes.
If you’re interested here is an explanation of some parts of the code. The fillet of the cube shaped parts of the hook is created with the fillet module. Within this module I simply intersect a cylinder with radius r1 and a cube of the desired length l.
OpenSCAD allows the user to create complex shapes with the polygon function for 2D and polyhedron for 3D. Polygon and polyhedron both accept a list of 2D and 3D coordinates (points) respectively as parameters. A functions can generate a list of points eliminating the need to manually created these lists. This property can be used to create shapes that are impossible with the 2D and 3D shapes that are build-in in OpenSCAD. In this blog post I’ll show how to create some simple 2D and 3D shapes and explain how to create more complex shapes.
Creating a 2D shape
To create a circle with a radius of 20 in OpenSCAD we just have to type
However OpenSCAD doesn’t allow us to reshape this build-in function to for instance an ellipse. Alternatively we can write a function that generates a list of points needed for a circle and then use polygon with the points as parameter to draw the circle. The function uses the trigonometric formulas, x = r cos φ and y = sin φ, to convert polarcoordinates to Cartesian coordinates.
When F5 is pressed a circle is drawn however the x,y coordinates of this circle are available to us. By adding echo(circle(20)); to our script the list of points is printed in the console. The circle function can easily be altered thus gaining a new shape. An example is shown below.
Now let’s take a look at the syntax of the function. Every function generates a value and in this case it is a list of points. In OpenSCAD a list of points in a two-dimensional space is represented by [[x1,y1],[x2,y2],[x3,y3],…] where all x’s and y’s are numbers. In this case of the circle function the point are generated in a for loop. The loop begin at 0 and ends at 720 with a step of 1. The radius * cos(phi/2) and radius * sin(phi) calculate each x,y coordinate for every given phi.
The ellipse, a generalization of the circle, can now easily be created by slightly changing our function.
a second parameter is added. r1 is the radius in the x-direction and r2 is the radius in the y-direction. If r1 is equal to r2 a circle is drawn.
Creating a 3D shape
To create a 3D shape is more complex than 2D. We use polyhedron function of OpenSCAD instead of polygon. For polyhedron to work we need a list of 3D points instead of 2D points and in addition a list of faces. Each face contains the indices of 3 or more point. All faces together should enclose the desired shape. So let’s start create a cylinder. First we need to calculate a list of the points of the cylinder.
h = 180; //height of the shape
step = 18; //height of one layer of the shape
a = 36; //step size for angle in degrees
r = 40; //radius of the base of the vase
p = [for (z = [0:step:h], angle = [0:a:360-a]) [cos(angle) * r, sin(angle)* r,z]];
If you want to display these all the points in the list create the module plotList.
To display all the points in the list p in red type.
Press F5 and a cloud of points in the shape of a cylinder will appear.
Next we need a list of faces. This is often the most difficult part. In this case we create faces that consists of four points.
Imagine that we define a matrix that has n columns and m rows and we use this to systematically work our way through the points to create perfectly connected rectangles. So the first rectangle will be [0,1,7,6], the second [1,2,8,7] etc.
If we want to translate the complete matrix above we need the code below. Note that instead of using fixed numbers for the matrix the size of the matrix is calculated based on the variables that we defined earlier.
m = floor(h/step); //number of rows in matrix
n = floor(360/a); //number of columns in matrix
fcs = [for (j = [1:m], i = [0:n-2]) [(n*(j-1))+i,(n*(j-1))+i+1,(n*j)+1+i,(n*j)+i]];
We are getting there but we also need to create a top and bottom separately or else we wouldn’t get a solid.
top = [for (i = [n*m:(n*m)+n-1]) i];
bottom = [for (i = [0:n-1]) i];
And we need to connect or stitch the end points by creating additional faces of each row of the matrix. For example [0,5,11,6] for the first row.
You could ask why choose such a complex method to create a cylinder. However just as with polygon this method enables us to create shapes that are impossible to do otherwise in OpenSCAD. Imagine to have the z-direction smoothly curved and on top of that have a periodic curve in the xy-plane of the shape. We would end up with a vase shown in the image below. It’s impossible to create this shape in another way in OpenSCAD. In a next post I’ll explain how to do that.
OpenSCAD allows the user to create complex 2D shapes using functions that generate lists of points This list is used as the argument in the polygon function of OpenSCAD. Every shape can be generated as long as the mathematical expressions are known and can be translated to OpenSCAD script. This opens up a world of possibilities. The same is true for 3D shapes but instead of polygon the more complex polyhedron function of OpenSCAD should be used.
Caveat: List comprehensions as shown in the functions of this article are only possible with OpenSCAD v2015.03 and above.
OpenSCAD is open source (GPLv2 license) and is well maintained by Marius Kintel et al. Besides the stable releases for Windows, OSX and Linux, developmentsnapshotsare available. I recommend using these development snapshots since they have all the latest features.
EDIT: If you render the cylinder that we created above, export it as an .stl file and import it in Prusaslicer you’ll see a message like “auto-repaired 2246 errors”. This problem is caused by the reversed normals on (part of) the faces. I’ll demonstrate how to solve this in a next post. The model however prints fine thanks to Prusaslicer.
My third post on Bash scripting. This time I used a loop in the script. It’s still a simple script but also a very useful one. I regularly import photos from my digital camera or from my smartphone. The file names of these photos are either a number or a random string of characters. I like to rename these photos to give them a more meaningful name for instance summer2018.
The script lets me choose a folder and next asks for a file name. Then the script determines whether the folder exists and if it does it copies all .jpg files and gives the copied files a new name and a number starting with 0 and increasing the number with one for every photo in the folder. The files are copied so the old files still exists just in case a mistake was made. If I’m satisfied I delete the original files manually.
Question: I’d rather have a file name number with three decimals starting from 000 but I haven’t got I clue how to do that. Any ideas?
If you want to use this script, copy the code below and paste it into an editor like vim, vi or Geany. Save it e.g under the name rename and make this file executable by typing.
chmod 755 rename
To run the script just type.
2 # written by Eric Buijs 29 januari 2019
3 # rename changes all the jpg files in a user specified folder
7 read -p 'type the name of the folder here (e.g: /Users/myname/Documents): ' dname
9 read -p 'type the new name of the files (without extension): ' fname
11 if [ -d $dname ]
13 echo directory exists
14 cd $dname
15 echo $dname
17 for file in $files
19 cp $file $dname/$fname$counter.jpg
23 echo directory does not exist
26 echo 'All done'
As a follow up on my Bash scripting efforts that I started this year I wrote a script that resizes a photo to a specified width in pixels. The script should work both on Linux and OSX (tested on OSX, will test on Linux later). For this script to work ImageMagick needs to be installed. The script tests if an argument is specified (the original photo of course), if ImageMagick has been installed and if the file output.jpg exists. If output.jpg exists the user gets the option to overwrite the existing file or exit the script. Finally the user needs to specify the width in pixels of the output.jpg.
If you want to use this script, copy the code below and paste it into an editor like vim, vi or Geany. Save it e.g under the name resize and make this file executable by typing.
chmod 755 resize
Now if the photo is in the same folder as the script just type.
# written by Eric Buijs 12 january 2019
if [ $# -eq 0 ]
echo You need to specify a file.
echo e.g: resize photo.jpg
if [ ! $(which convert) ]
echo This script requires Imagemagick!
echo You can download it at http://www.imagemagick.org/
if [ -e output.jpg ]
echo output.jpg already exists.
read -p "Do you want to overwrite it? (Y/N) " answer
if [ $answer = "N" ]
read -p "What is the desired width in px: " width
convert $1 -resize $width output.jpg
To kick off the year I started to learn Bash scripting, something I wanted to do a very long time. I humbly began with tutorials on the web like this one and I’m rewriting scripts from Smokey01, a Puppy Linux user. As an exercise I simply rewrote this script to work on OSX. If you want to use it you need to install exiftool. I installed exiftool with Homebrew and typed brew install exiftool but there’s also a dmg file available. If you don’t use Homebrew you do have to change the check if exiftool is installed.
Now for the script. It reads a jpeg file that must contain geo-coordinates. After some checks for parameter and exiftool installed it reads the geo-coordinates and stores them in the variable coord. This variable is then added to a Google search query and the result displayed in the browser.
Save the script e.g. with the name place and run with place /path/to/photo.jpg to display the location where photo.jpg was taken.
2 # Originally written by smokey01 28 May 2017
3 # Rewritten for OSX by Eric Buijs 9 Jan 2019
4 if [ $# -eq 0 ]
6 echo You need to specify a file.
7 echo EG: place photo.jpg
8 exit 1
11 if [ ! -d /usr/local/Cellar/exiftool ]
13 echo "This script requires exiftool!"
14 exit 1
17 coords=`exiftool -n -p '$GPSLatitude,$GPSLongitude' $@`
18 read -e -p "Do you want to see the location in your Browser? " choice
19 [[ "$choice" == [Yy]* ]] && open https://www.google.com/search?q=$coords || exit 1