Generating Custom Shapes in Tinkercad for 3D printing via Bezier Geometry and Javascript

Week 1

Play the great Bezier applet

The quadratic Bezier Curve connects A = (Ax,Ay) to B = (Bx,By)
while being "controlled" by C = (Cx,Cy)

via

x(t) = (1-t^2)Ax + 2t(1-t)Cx + (t^2)Bx

and

y(t) = (1-t^2)Ay + 2t(1-t)Cy + (t^2)By

as t travels from 0 to 1

with   Ax = 100, Ay = 100   Bx = 400, By = 300     Cx = 400, Cy = 100

For example, if t=1/10 then

x(1/10) = (1-1/100)100 + (2/10)(1-1/10)400 + (1/100)400
        = (99/100)100 + (2/10)(9/10)400 + 4
        = 99 + 18*4 + 4
        = 175

and

y(1/10) = (1-1/100)100 + (2/10)(1-1/10)100 + (1/100)300
        = (99/100)100 + (2/10)(9/10)100 + 3
        = 99 + 18 + 3
        = 120

Complete the table

t 	|  	x(t)	|	y(t)
0       |	100	|	100
1/10    |	175	|       120
2/10    |       240     |       140
3/10    |       295     |       160
4/10    |       340     |       180
5/10    |       375     |       200
6/10    |       400     |       220
7/10    |       415     |       240
8/10    |       420     |       260
9/10    |       415     |       280
1 	|	400	|	300

and build this curve on the floor

Week 2


next build and test javascript here

create an account 

adapt its Canvas Triangle Code Sample to read


<canvas id="canvas1" width=500 height=400></canvas>
<script>
var c=document.getElementById('canvas1').getContext('2d');
c.fillStyle = "Linen";
c.fillRect (0,0,500,400); // Background rectangle
var Ax = 100;
var Ay = 100;
var Bx = 400;
var By = 300;
var Cx = 400;
var Cy = 100;
c.moveTo(Ax,Ay); // Place pen at A
var t = 0.5;
var x = (1-t*t)*Ax + 2*t*(1-t)*Cx + t*t*Bx;
var y = (1-t*t)*Ay + 2*t*(1-t)*Cy + t*t*By;
c.lineTo(x,y); // Second point
c.stroke();
var t = 1;
var x = (1-t*t)*Ax + 2*t*(1-t)*Cx + t*t*Bx;
var y = (1-t*t)*Ay + 2*t*(1-t)*Cy + t*t*By;
c.lineTo(x,y); // third point
c.stroke();
</script>


Please strive to understand every line of this code. Experiment.

This is better than completing the table by hand (but not by much)

Week 3


Next economize by looping over many values of t. That is, code


<canvas id="canvas1" width=400 height=300></canvas>

<script>
var c = document.getElementById('canvas1').getContext('2d');
c.fillStyle = "Linen";
c.fillRect(0,0,400,300); // Background rectangle
var Ax = 100;
var Ay = 100;
var Bx = 400;
var By = 300;
var Cx = 400;
var Cy = 100;
c.moveTo(Ax,Ay); // Place pen at A
for (var i=1; i<100; i=i+1){    // i is our "counter"
    var t = i/100;  // t moves from 0 to 1 in steps of 0.01
    var x = (1-t*t)*Ax + 2*t*(1-t)*Cx + t*t*Bx;
    var y = (1-t*t)*Ay + 2*t*(1-t)*Cy + t*t*By;
    c.lineTo(x,y); // next point
    c.stroke();
}

</script>


again strive to understand every line, experiment, ...

Next return to the Bezier applet and return to code your own cubic Bezier Curves.

Next open a new browser tab and visit
Tinkercad

Create an account if don't already have one.

Click on    Create New Design   and tinker with Basic Shapes, refresh
your understanding of dimensions, holes and grouping.

Next click the arrow at the right of Basic Shapes and from the drop down
menu select   Featured Shape Generators.  This is where things get
interesting. Drag the softbox onto your workplane, play with its sliders,
click on "view code" and contrast it to what you've learned about
javascript.

Week 4


Return to Tinkercad, then from menu at right choose Featured Shape Generators
and from there drag the SoftBox onto your workplane.

Take a minute to play with the sliders and note how smooth those corners are.

Just below the sliders click on "View Code" 

I hope that you recognize this as javascript

The first 15 or so lines are just definitions, pass them by for lines like

quadraticCurveTo(Cx,Cy,Bx,By)

It draws a quadratic Bezier curve from the previous point to (Bx,By) using
the control point (Cx,Cy) to bend the curve - just as you have learned to do.

This command is the real workhorse of the softbox - everything else is just 
building sliders to specify points for your softbox. 

Do you see how the sliders function and how they are coded?

Lets make a copy of this code that you can then edit and experiment with.

Highlight and copy the code.

Click on 3-by-3 block next to the pick (voxelizer) to return to the 
Tinkercad Editor.

In menu at right select "Your Shape Generators"

Select "New Shape Generator"

Select "Empty"

Highlight the code and paste (this will replace the Empty code with SoftBox)

Now click on Settings and change the library name to "mySoftBox"

Click Save and now start to experiment with various choices of 
(Bx,By) and (Cx,Cy). 

Next to switch from quadratic to cubic please experiment with

bezierCurveTo(C0x,C0y,C1x,C1y,Bx,By)

From here you may wich to go back to the "New Shape Generator" and
start off from the other preset templates.

For example, "Heart" is made completely from Bezier Curves.

For the more adventurous I recommend a tour of the "Icosahedron"
and for those curious about the magic of sine and cosine I recommend
the twisted polygon.

Week 5


Return to Tinkercad, then from menu at right choose Featured Shape Generators
and from there drag the Arch Building Blocks onto your workplane.

Take a minute to play with the sliders and note how smooth those corners are.

Just below the sliders click on "View Code"

I hope that you recognize this as javascript

// -------------------------------------------
// Added Automatically During Library Upgrade.
// Convenience Declarations For Dependencies.
// 'Core' Is Configured In Libraries Section.
// -------------------------------------------
var Debug = Core.Debug;
var Mesh3D = Core.Mesh3D;
var Path2D = Core.Path2D;
var Plugin = Core.Plugin;
var Tess = Core.Tess;
var Solid = Core.Solid;

// -------------------------------------------
// Original Shape Script:
// -------------------------------------------
params = [
		{ "id": "l", "displayName": "Length", "type": "length", "rangeMin":1, "rangeMax": 100.0, "default": 20.0 },
		{ "id": "w", "displayName": "Width", "type": "length", "rangeMin": 1, "rangeMax": 100.0, "default": 10.0 },
		{ "id": "r", "displayName": "Radius", "type": "length", "rangeMin": 1, "rangeMax": 100.0, "default": 5.0 }
		]
	
	function process(params) { 
		
		//parameters
		var l = params.l;
		var w = params.w;
		var r = params.r;

		if(l/2 < r && w < r) {
			
			if(l/2 < w){
				
				var r = l/2;
			}
			else{
				
				var r = w;
			}
						
		}	
		
		else if (l/2 < r ){
			
			var r = l/2;
		}
		
		else if (w < r ){
			
			var r = w;
		}
		
		else {
			var r = r;
		}
					
					
		var path = new Path2D( );
		path.moveTo(0, 0);
		path.lineTo(l/2-r, 0);
		path.quadraticCurveTo(l/2-r, r, l/2, r);
		path.quadraticCurveTo(l/2+r, r, l/2+r, 0);
		path.lineTo(l, 0);
		path.lineTo(l, w);
		path.lineTo(0, w);
		path.lineTo(0, 0);
	
		var solid = Solid.extrude( [path], 5 );	
		
		return solid;
	
}
// -------------------------------------------
// Added Automatically During Library Upgrade.
// Original Shape Color. Changing Effects The
// Default Color In All Documents Where Used.
// -------------------------------------------
presets = [
	{ 'color': [117, 206, 219] }
];


Do you see the parameters l, w and r that define length, width and radius?

Do you understand what this big unwieldy if clause is doing?

It is making sure that the radius is less than both the width and half the length.

Do you see that we can replace it with the two lines

      r = Math.min(r,w);
      r = Math.min(r,l/2);

Next lets follow the moveTo, lineTo and quadraticCurveTo lines of code

What happens if we replace the pair

	path.quadraticCurveTo(l/2-r, r, l/2, r);
	path.quadraticCurveTo(l/2+r, r, l/2+r, 0);

with

        path.quadraticCurveTo(10, 30, l/2+r, 0);

and similarly, what happens if I replace

	path.lineTo(0, w);

with

	path.quadraticCurveTo(10, 30, 0, w);