# 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

<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 open a new browser tab and visit

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

```
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

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

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).

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

```
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

// -------------------------------------------
// 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.lineTo(l, 0);
path.lineTo(l, w);
path.lineTo(0, w);
path.lineTo(0, 0);

var solid = Solid.extrude( [path], 5 );

return solid;

}
// -------------------------------------------
// 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);

What happens if we replace the pair

with