Pages

Showing posts with label creative coding. Show all posts
Showing posts with label creative coding. Show all posts

Thursday, December 14, 2017

OpenSCAD: Generating Triangles and Poyhedron

Polyhedron, vertices and faces

OpenSCAD offers three methods to make 3D model. First is Constructive Solid Geometry where primitive objects are combined using boolean operations. The second method uses two dimensional shapes that are extruded either in the z direction (linear_extrude)) or around the the z-axis (rotate_extrude). In the third method vertices (or points) and faces are defined to shape the surface of a 3D model (polygon mesh). This, at least in theory, provides us with a method to create the most complex 3D shapes.

Polygon mesh of a dolphin. In this example a triangle mesh is used. A public domain image from Wikipedia (https://en.wikipedia.org/wiki/Polygon_mesh#/media/File:Dolphin_triangle_mesh.png)

The third method can be achieved with the polyhedron function of OpenSCAD. The description polyhedron function in the OpenSCAD manual is more than adequate but it only provides the user with examples where the vertices and faces are manually entered in OpenSCAD. This can be a cumbersome process that is prone to bugs, leading to a non-valid solid. Having OpenSCAD generate these vertices and faces is a method that is more favorable (at least to me) for two reasons. First once the algorithm is correct the chance to generate non-valid solids is minimized but more importantly computer is so much faster in calculating the vertices needed.

Triangle mesh of a sphere

An important question is what kind of faces are needed for our polygon mesh. From OpenSCAD version 2014.03 onward a face description can have any number of vertex larger than two however I think that the triangle mesh is still the best choice. If the user chooses more than three vertices OpenSCAD subdivides the faces to triangles and this can cause problems as is demonstrated in an article of Justin Lin where a cube that consist of four vertex faces and one of the faces is not planar with the other three. So in conclusion the triangle mesh provides the best control over the 3D model in OpenSCAD.

In the following video tutorial I'll explain how to create such a 3D model of a sphere, cone, torus and cylinder in OpenSCAD.

Here is a link to the video:

https://peertube.linuxrocks.online/w/mohQABzAQ7FVapu4npswoJ

Tuesday, October 3, 2017

OpenSCAD Essentials: Lists and list manipulation

Lists

This is the second part in a series on OpenSCAD (here is a link to the first). This series will not cover the very basics of OpenSCAD, there is plenty of good material on that, but it's for those who want to advance beyond these basics. This part is about Lists, sequences of OpenSCAD values. These are very important in OpenSCAD because they are the equivalent of arrays. They're also referred to as vectors. Lists can contain values numbers, booleans and strings. For most examples below version 2015.03 is required.

Quicksort example from the OpenSCAD User Manual demonstrates how to manipulate a list. The red row of cylinders represents the unsorted list while the green row represents the sorted list.

First let's create some lists by typing the following in the OpenSCAD editor.

lst = [1,2,3,4,5,6,7,8,9]; //a list of numbers
lst2 = ["red","yellow","blue"]; //a list of strings
lst3 = [false,true,undef]; //a list of booleans
echo(lst);
echo(lst2);
echo(lst3);

In OpenSCAD the user is able to automatically generate lists with for, if and let. A couple of examples

lst4 = [for (i = [0:9]) i*i];

This generates a list of [0, 1, 4, 9, 16, 25, 36, 49, 64, 81], so for every i the results is i multiplied by i. OpenSCAD even allows nested loops

lst5 = [for (i = [0:2]) for (j =[0:2]) for (n=[0:2]) [i,j,n]];

This generates a list of a long list of vectors ECHO: [[0, 0, 0], [0, 0, 1], [0, 0, 2], [0, 1, 0], [0, 1, 1], [0, 1, 2], [0, 2, 0], [0, 2, 1], [0, 2, 2], [1, 0, 0], [1, 0, 1], [1, 0, 2], [1, 1, 0], [1, 1, 1], [1, 1, 2], [1, 2, 0], [1, 2, 1], [1, 2, 2], [2, 0, 0], [2, 0, 1], [2, 0, 2], [2, 1, 0], [2, 1, 1], [2, 1, 2], [2, 2, 0], [2, 2, 1], [2, 2, 2]]

Manipulate a list

A list in OpenSCAD can be manipulated with a function. Manipulation is needed in order to make changes to the list. Since OpenSCAD is a Functional Language we can't just for example change value in the list. We need a function to do this. Lets assume we want to create a partial list from an existing list. We then create the following function:

function partial(list,start,end) = [for (i = [start:end]) list[i]];
echo(partial(lst,1,8));

In the Console of OpenSCAD the following is displayed ECHO: [2, 3, 9, 5, 6, 7, 8, 4]. The function has three parameters: a list, a start number and an end number. The function iterates through the list and then creates a new list with the items with indices 1 to 8. Note that the first item in the list with index 0 has been excluded from the new list. Another example.

echo(partial(lst,4,7));

This prompts ECHO: [5,6,7,8], a list with the 4th to the 7th item of lst. Remember that lst itself hasn't changed (you can check this yourself). Next we write a function to remove a number in a list.

function remove_item(list,position) = [for (i = [0:len(list)-1]) if (i != position) list[i]];
echo(remove_value(lst,2));

This prompt ECHO: [1,2,4,5,6,7,8,9], the third item in the list has been removed. The function, that has the parameters list and position, loops through the items of the list and if the index i is not equal to the parameter position it is added to the new list. In this example it means that the item with the index 2 is not part of the new list. The following function inserts a value instead of removing it.

function insert(list,value,position) = let (l1 = partial(list,0,position-1), l2 = partial(list,position,len(list)-1)) concat(add_value(l1,value),l2);
echo(insert(lst,10,4));

It cuts the list on the position 4 in two new lists, inserts a number of 10 between the two lists, using the function partial that was created above. The result in the console is: ECHO: [1, 2, 3, 4, 10, 5, 6, 7, 8, 9]. BTW: It's entirely possible that there's an easier way to do this.

The last and most complicated example is taken from the OpenSCAD User Manual and implements the quicksort algorithm. The quicksort function uses an unsorted list as input and produces a sorted list with a recursive method.

lst6 = [1,4,6,7,3,5,7,2]; //a list of numbers
function quicksort(list) = !(len(list)>0) ? [] : let(
    pivot   = list[floor(len(list)/2)],
    lesser  = [ for (i = list) if (i  < pivot) i ],
    equal   = [ for (i = list) if (i == pivot) i ],
    greater = [ for (i = list) if (i  > pivot) i ]
) concat(
    quicksort(lesser), equal, quicksort(greater)
);

echo(lst6);
echo(quicksort(lst6));

It produces the following output ECHO: [1,2,3,4,5,6,7,7]. The function starts with a base case !(len(list)>0) ? [] meaning if a the length of list is 0 return an empty list (or the boolean value false) else continue. Next a pivot is determined being the number in the middle of the list, in this case the number 3. Next all numbers in the list smaller than 3 are placed in a list lesser, all numbers equal to 3 are placed in a list equal and all numbers larger than 3 are placed in a list greater. These three list are then concatenated to a new list however, and now we get to the recursive parts, the lesser and greater lists are the new parameters for quicksort. This iteration continues until the base case, the length of the list is equal to zero or less, is reached.

Understanding lists and list manipulation is essential to advance in OpenSCAD. Without it would for instance be near impossible to work with the all important vectors in both 2D and 3D. But also in other areas, such as iterating through a row, lists are essential.

Friday, September 15, 2017

OpenSCAD Essentials: Functional Programming

Functional programming

OpenSCAD is a 3D CAD program where the 3D model is created with a script. Although the basics are very simple there is a point on the learning curve where the OpenSCAD programming language can become confusing. OpenSCAD is a Functional Programming Language and behaves differently than most people, used to the Imperative Programming Paradigm, expect. With Imperative Programming a value can be assigned to a variable and later another value can be assigned to same variable later in the program. This changes the state of the program. This approach will not work in OpenSCAD.

Sierpinski triangle in OpenSCAD. A program I made earlier that demonstrates recursion in OpenSCAD.

An example

The easiest way to explain this is with a simple example. In this example we want the program to add the numbers 1 to 10 (1+2+3+4+5+6+7+8+9+10).

total = 0;

module count(number) {
    for (i = [1:number]) {
        total=total+i;
    }
    echo(total);
}

count(10);

You might expect that the answer is 55 however to your horror you'll find in OpenSCAD that it actually is 0. What happened? Instead of assigning a new value to the variable total for every interation, total keeps it's initial value. The program written in OpenSCAD is a mathematical expression that is evaluated by pressing F5. OpenSCAD supports powerful functional constructs to support these expressions. In the case of the example above we write.

function sum(number) = (number == 0 ? 0 : number + sum(number-1));

echo(sum(10));

The result of this program is 55 as intended but how does it work. We define a function (hence the name Functional Language) sum with a parameter number. On the right side of the function there is an evaluation, in pseudocode: if n == 0 then 0 else number + sum(number-1). Notice that the function is recursive so for example for number is 3 the function evaluates as follows

sum(3) = 3 + sum(2) = 3 + 2 + sum(1) = 3 + 2 + 1 = 6

Iteration in OpenSCAD is usually accomplished via recursion. If you are not used to recursion it's takes effort and practice to understand but it's often simple and elegant. Now let's do a somewhat more complicated example, the greatest common devisor (gcd). When we look at gcd algorithms on wikipedia we find the recursive Euclidian algorithm which is described as follows:

gcd(a,0) = a
gcd(a,b) = gcd(b, a mod b)

Even if we would not understand the algorithm it's easy to translate it to OpenSCAD

function gcd(a,b) = b == 0 ? a : gcd(b,a%b);

Where a%b means a modulo b (BTW: the syntax used in the functions above is similar to the programming language C). It's worthwhile as a training to find recursive algorithms and try to implement them in OpenSCAD.

Further reading

If you want to advance in OpenSCAD it is necessary to read the manual at some point. This discloses valuable information that is hard to find by just using the Cheatsheet or the watching YouTube videos. The user manual can be found here: https://en.wikibooks.org/wiki/OpenSCAD_User_Manual/The_OpenSCAD_Language

Tuesday, June 20, 2017

Line and Polyline modules in OpenSCAD

Polygon in OpenSCAD

The polygon function of OpenSCAD is very cool but for some applications it just doesn’t cut it. For instance when polygon is used to draw a Starpolygon, a self intersecting polygon, the space between the polygon lines is filled, an undesired effect that cannot be negated. In case of the Starpolygon we just want to see the lines.

Line and Polyline

Luckily we can create our own polygon module in OpenSCAD that meets our needs. However before we can create a polygon we need to be able to create a single line. Also a single line can be created in OpenSCAD, actually in several ways. In the YouTube video below I'll show one such approach.

A Vase created with line, polyline and rotate_extrude in OpenSCAD.

Furthermore I’ll show how to create a line module and a polygon module that fit our needs but it doesn’t stop there. With the line and polyline a complete 2D-library in OpenSCAD can be created. Also, in combination with linear_extrude and rotate_extrude 3D objects can be created that are impossible to create with CSG alone.



In a next blogpost I’ll show you how to create a Bezier Spline with line and polyline. This Bezier Spline can then be used to create a smooth curve needed in a 3d printable vase for example.

I want to mention Justin Lin here. He has a great website www.openhome.cc where he, not only shares his OpenSCAD work, but also explains it in great detail. I think it’s a very useful resource for OpenSCAD.

The file of this video can be downloaded with the following link: https://drive.google.com/open?id=0Bwg0RBbuN0fMVkJISXdDQV9sekE

OpenSCAD is open source (GPLv2 license) and is well maintained by Marius Kintel et al. Besides the stable releases for Windows, OSX and Linux, development snapshots are available. I recommend using these development snapshots since they have all the latest features. 

Tuesday, May 30, 2017

Spiral Phyllotaxis patterns in OpenSCAD

Spiral Phyllotaxis

In just uploaded a YouTube video about Spiral Phyllotaxis patterns in OpenSCAD. This time it’s a script that I made to demonstrate Spiral Phyllotaxis. Phyllotaxis is a term used for patterns that emerge during the growth of plants. Spiral Phyllotaxis is observed in the heads of sunflowers, in pine-cones and pineapples, and in a variety of other plants.

The script that I wrote uses a mathematical description of Spiral Phyllotaxis called Vogel’s formula. Vogel’s formula actually exists of two equations, one for an angle theta, and one for a radius, describing the a pattern of seeds in a sunflower head. I’ll put a link in the description if you want to know more about Vogel’s formula. These simple equations can generate beautiful patterns that have some interesting mathematical properties.

The number of spirals derived from Vogel’s formula has a close relationship with the Fibonacci sequence. Exactly 55 spirals go counterclockwise, 34 smaller spirals go clockwise and 21 even smaller spirals go counterclockwise and so on. These numbers of spirals are all integers in the Fibonacci sequence.

The Golden Angle or Fibonacci Angle of 137.5 degrees is key in these Spiral Patterns. This angle results in the best distribution of the seeds. A slightly smaller or larger angle leads to a less optimized distribution.

Not only can the Spiral Pattern be examined in OpenSCAD. A big bonus of the program is that the user can create an stl file that can be printed. The physical model can then be studies further.

Sunday, May 7, 2017

Video on 2D Supershapes created in OpenSCAD

2D Supershapes

I just uploaded a video on 2D Supershapes created in OpenSCAD, the open source 3D CAD program. 2D Supershapes are based on an equation, the Superformula, proposed by John Gielis around 2000. Gielis suggested that the formula can be used to describe many complex shapes and curves that are found in nature. The possibilities with the Superformula seem endless. OpenSCAD not only let you recreate these Supershapes but also enables the you to 3D print the shapes.

Wednesday, April 12, 2017

TIE fighter in OpenSCAD

Introduction

OpenSCAD is an excellent 3D CAD tool to create space craft because of their symmetrical, non-organic shape. This video of a space ship is a good example. However I couldn't find much Star Wars models made in OpenSCAD. So I decided to do it myself and start with a simple TIE fighter.

TIE fighter made in OpenSCAD.

 

Design

When I create a model like this I start with simple primitives and get the position right. In this case a sphere that represents the command pod, two cones that act as pylons and two hexagons as solar arrays. Once I have a basic TIE fighter I start shaping the different parts. Since all these parts are modules this doesn't interfere with the positioning.

Most basic shape of a TIE-fighter consisting of a sphere, two cones and two hexagons. Hexagons still need a 30 degrees rotation around the x-axis.

I use a couple of global constants that mainly determine the positioning of the different parts of the TIE fighter. The're seperate modules for the command pod, solar array and the wing pylon. Also a seperate module exists for the solar panels that are part of the solar array.

Most of the code is pretty standard OpenSCAD maybe with the exception of the solar array. The solar panel is created with a polygon which is a trapezoid. The trapezoid needs to fit between the inner en outer hexagon therefore the points of the trapezoid are depending on these hexagons of the solar array. The angle of the trapezoid is 120 degrees enabling me to calculate the all points of the trapezoid solar panel with basic trigonometry. The variable delta in the solar_panel module enables us to create and edge on the solar_array.

//Modules
module solar_array (outer_radius, inner_radius) {
    difference() {
        union() {
            cylinder(r=outer_radius,h=2,$fn=6);
            cylinder(r=inner_radius,h=4,$fn=6);
        }
        for (i=[1:6]) {
            rotate([0,0,i*360/6]) translate([0,inner_radius,0]) translate([0,0,1]) solar_panel(outer_radius,inner_radius);
            rotate([0,0,i*360/6]) translate([0,inner_radius,0]) translate([0,0,-0.3]) solar_panel(outer_radius,inner_radius);
        }
    }
}

module solar_panel(outer_radius, inner_radius) {
    //delta determines the size of the edge of the solar array.
    delta = 3;
    //x and y determines outer side of the solar panel trapezoid
    x = inner_radius/2 + sin(30) * (outer_radius-inner_radius-delta);
    y = cos(30) * (outer_radius-inner_radius-delta);
    echo(x,y);
    list = [[-inner_radius/2,0],[inner_radius/2,0],[x,y],[-x,y]];
    linear_extrude(1)
    polygon(list);
}

The TIE fighter model is largely parametric meaning that the most of the design of the model can easily can be changed by changing the parameters (constants). This model of the TIE fighter can is still rather basic but it can be expanded by modifiying the different modules.

3D printing

Until now I didn't feel the need for 3D printing the model (my extruder is in repair anyway) but with a few modifications printing shouldn't be a problem. I would print the command pod first and attach the solar array with wing pylon later.

The OpenSCAD file of the TIE fighter can be found here.

OpenSCAD is open source (GPLv2 license) and is well maintained by Marius Kintel et al. Besides the stable releases for Windows, OSX and Linux, development snapshots are available. I recommend using these development snapshots since they have all the latest features.



Friday, March 17, 2017

Creating a mathematical rose in OpenSCAD

Introduction

In my previous blog post I explained how to create complex 2D shapes in OpenSCAD. Once a mathematical expression for a shape is known it's possible to translate it to OpenSCAD script. The Carthesian coordinates of mathematical rose, a rose shaped sinusoid, can be expressed by x = cos(kθ)cos(θ) and y = cos(kθ)sin(θ). If k is an integer a the shape will be relatively simple but is k is a fracture more complex shapes are created.

One of the shapes that can be created with the rose_points function (linear_extrude is used to create a 3D shape).

Writing the script

All the points needed to create the rose will be generated in the function rose_points. Rose
_points returns these points in a list. The function will have the form:

function rose_points(k,n,radius) = [...]

The parameters k and n will determine the shape of the rose. If n = 1 the curve will a simple rose shape but if n > 1 more complex shapes are drawn. Here is a link to all the possible shapes when varying k and n. The syntax of OpenSCAD for lists allows us to use if and for elements to construct a list. In the case of our function we can use these elements.

step = 1;
function rose_points(k, n , radius) = k%2 == 0 && n%2 ==1 ? [for (theta = [0 : step : 360 * n]) [radius * cos(k/n*theta) *sin(theta), radius * cos(k/n*theta) * cos(theta)]] : [for (theta = [0 : step : 180 * n]) [radius * cos(k/n*theta) * sin(theta), radius * cos(k/n*theta) * cos(theta)]];

a=rose_points(5,7,100);
color("red") polygon(a);

The function looks intimidating at first due to the list comprehensions.  The key is to just break it apart. The two parts between square brackets contain lists of points (generated by a for loop). The rest is an if, then, else statement: if k is even and n is uneven then [] else []. More information on the syntax for a list (list comprehensions) can be found here.

The function isn't perfect. With some combination of k and n (e.g. 6 and 2) nothing is displayed on the screen. The reason is that with this combination all points are repeated prompting the polygon function of OpenSCAD to draw nothing. In this cases it helps to change the range of theta.

Caveat: List comprehensions as shown in the rose_points function 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, development snapshots are available. I recommend using these development snapshots since they have all the latest features. 

Shape created with k = 2 and n = 1.

Shape created with k =8 and n = 7.


Saturday, March 4, 2017

Getting creative with OpenSCAD

Introduction

OpenSCAD is software to create solid 3D CAD Models but other than most 3D CAD programs a model can be created with a programming language. Although OpenSCAD is often used to create models for 3D printing it also very capable as a tool for creative coding. Creative coding is more about being expressive than being functional.

Sierpinski triangle made in OpenSCAD (recursive algorithm).


Creative coding

I've been using OpenSCAD for over a year now for my 3D printing projects but as of late I'm exploring the creative possibilities of this programming language. It all started when I was watching another episode of The Coding Train, a great and often hilarious YouTube channel from Daniel Schiffman. In this show Daniel Schiffman takes on coding challenges. These coding challenges can be a physics simulation, data visualization or computer vision. While watching the show I was wondering which tool would be suitable to take on these challenges myself. Schiffman is mainly using Processing and P5.js which aren't in my skill set. I have a basic understanding of Python but not enough to start coding these challenges. OpenSCAD has become the programming tool that I'm most familiar with so I figured to give it a try.

OpenSCAD is pretty well equipped for creative coding. No need to import additional modules or libraries to draw onto the screen. It also comes with ready to use 2D and 3D primitives, geometric transformations and boolean operations for 2D and 3D primitives. OpenSCAD is a functional programming language as opposed to most common programming languages such as Python, C and Java which are imperative languages. In OpenSCAD variable keeps one value so i  = i + 1 won't work and f(x) will always produce the same result for a given x (as in mathematics). Once you get your head around that working with OpenSCAD becomes easy.

OpenSCAD doesn't disappoint for creative coding. Although some challenges didn't seem possible with OpenSCAD, because of the limited animation features of the program (or my lack of understanding of these features, others could be easily achieved with it. Below are examples of challenges that I did with OpenSCAD.


Mathematical rose pattern made in OpenSCAD.

Phyllotaxis pattern made in OpenSCAD.

Openhome.cc

Along the way I discovered that I'm not the only one using OpenSCAD for creative programming. I like to mention the website openhome.cc which has an excellent OpenSCAD section. This section not only explains the underlying fundamentals of OpenSCAD but also has creative chapters about spirals, turtle graphics and maze.

OpenSCAD is open source (GPLv2 license) and is well maintained by Marius Kintel et al. Besides the stable releases for Windows, OSX and Linux, development snapshots are available. I recommend using these development snapshots since they have all the latest features.