craft-bowl
Version:
230 lines (187 loc) • 9.14 kB
text/xml
<craft name="bowl">
<parameter name="resolution" type="int" default="4"/>
<parameter name="depth" type="float" default="0.5"/>
<script type="text/openjscad">
function main(params)
{
if(params.depth > 2 || params.depth <= 0) params.height = 2;
if(params.resolution <= 3) params.resolution = 32;
if(params.radius <= 0) params.radius = 1;
return bowl(params);
}
function bowl(params)
{
return vessel({
'base_radius':params.radius,
'sequences':[
{'curve_radius':0.1,
'curve_angle':10,
'clockwise_curving':false,
'neck_length':params.depth},
{'curve_radius':0.3,
'curve_angle':55,
'clockwise_curving':false,
'neck_length':0.1},
{'curve_radius':0.3,
'curve_angle':30,
'clockwise_curving':true,
'neck_length':params.depth},
{'curve_radius':0.05,
'curve_angle':90,
'clockwise_curving':false,
'neck_length':0.01},
{'curve_radius':0.05,
'curve_angle':90,
'clockwise_curving':false,
'neck_length':params.depth},
{'curve_radius':0.4,
'curve_angle':30,
'clockwise_curving':false,
'neck_length':0.1},
{'curve_radius':0.2,
'curve_angle':55,
'clockwise_curving':true,
'neck_length':params.depth-0.1}
],
'thickness':0.1,
'no_of_sides':params.resolution,
'preview':false
});
}
function vessel(params)
{
var last_point = [];
var last_angle;
var points = [];
//vars
var base_r = params.base_radius || 1;
if(base_r <= 0) base_r = 0.5;
var sequences = params.sequences;
var skip_map = params.skip_map;
if(!skip_map)
{
skip_map = new Array(sequences.length);
for(var i = 0; i < skip_map.length;i++) skip_map[i] = 0;
}
var thickness = params.thickness || 0.1;
//check all sequence parameters and find smallest r
var min = thickness;
for(var i = 0; i < sequences.length; i++)
{
//check parameters
if(!sequences[i].curve_radius) sequences[i].curve_radius = base_r*0.5;
if(sequences[i].curve_angle <= 0) sequences[i].curve_angle = 10;
if(sequences[i].neck_length <= 0) sequences[i].neck_length = base_r*0.1;
//find min
if(!skip_map[i] &&
!sequences[i].clockwise_curving &&
min > sequences[i].curve_radius)
min = sequences[i].curve_radius;
}
if(thickness > min) thickness = 3*min/4;
var sides = params.no_of_sides ||32;
if(sides < 3) sides = 3;
var preview = params.preview || false;
//------------------
//outter base
points =[[0,0],
[base_r*0.9,0],
[base_r*0.9,-base_r*0.1],
[base_r,-base_r*0.1]];
last_point = [base_r,0];
last_angle = 360;
for(var i = 0; i < sequences.length; i++)
{
var seq = sequence(last_point,last_angle,sequences[i]);
last_point = seq.lastPoint;
last_angle = seq.lastAngle;
points = points.concat(seq.sequence);
if(i == sequences.length-1){points[points.length] = last_point;}
}
//get point C
last_point = [//x
last_point[0] -
sequences[sequences.length-1].curve_radius*Math.cos((last_angle + 90)*Math.PI/180) -
sequences[sequences.length-1].neck_length*Math.cos((last_angle)*Math.PI/180)
,
//y
last_point[1] -
sequences[sequences.length-1].curve_radius*Math.sin((last_angle + 90)*Math.PI/180) -
sequences[sequences.length-1].neck_length*Math.sin((last_angle)*Math.PI/180)
];
//update last angle
last_angle += 180;
// for(var i = sequences.length-1; i > 0; i--)
// {
// addSequence({'curve_radius':sequences[i].curve_radius,
// 'curve_angle' :sequences[i].curve_angle,
// 'clockwise_curving':sequences[i].clockwise_curving,
// 'neck_length' :sequences[i].neck_length
// });
// if(i == sequences.length-1){points[points.length] = last_point;}
// }
//
// points[points.length] = [0,thickness];
var c = cube();
if(preview)
c = rectangular_extrude(points,{w:0.05,h:0.05,closed:false});
else
c = rotate_extrude({fn:sides}, polygon({points:points}) );
//add smooth lip
//c = union(c,);
return c;
}
function sequence(last_point,last_angle,params)
{
//vars
var r = params.curve_radius;
var a = params.curve_angle;
var cw = params.clockwise_curving;
var l = params.neck_length;
//--------------
var square = 90;
//reset vars depending on ccw
if(cw){a *=-1;square *=-1;}
var gamma = last_angle + a;
var c = [last_point[0] + r*Math.cos((last_angle + square)*Math.PI/180),
last_point[1] + r*Math.sin((last_angle + square)*Math.PI/180)];
//add pie slice
var slice = pie_slice(c[0],c[1],r,last_angle - square,last_angle - square + a,10,cw);
//add neck
var neck_point = [//x
c[0] +
r*Math.cos((gamma - square)*Math.PI/180) +
l*Math.cos((gamma)*Math.PI/180),
//y
c[1] +
r*Math.sin((gamma - square)*Math.PI/180) +
l*Math.sin((gamma)*Math.PI/180)
];
return {'sequence':slice,'lastPoint':neck_point,'lastAngle':gamma};
}
function pie_slice(x,y,r,a1,a2,inc,clockwise)
{
var test = function(){return i < a2+inc;}
if(inc <= 0) inc = 10;
if(clockwise) {inc*=-1;test = function(){return i > a2+inc;}};
var result = [];
//generate points clockwise
for(var i = a1; test(); i+=inc)
{
result[result.length] = [r*Math.cos(i*Math.PI/180)+x,r*Math.sin(i*Math.PI/180)+y];
}
// //flip them if counter-clockwise
// if(false)
// {
// for(var i = 0; 2*i < result.length;i++)
// {
// var intermediate;
// intermediate = result[i];
// result[i] = result[result.length-i-1];
// result[result.length-i-1] = intermediate;
// }
// }
return result;
}
</script>
</craft>