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