While working on the design below in OpenSCAD, I realized that Boolean construction of a shape can become a bit counter intuitive when you start working with curves. The bottom of this box curves up but the curve is elliptical as well as the curves on either side. All curves are tangential to each other.
In order to construct shapes easily, I have been looking for a code based way to generate a shape outline. For that I have been taking queues from the SVG path specifications where you start at a given point and a sequence of instructions defines the path. I like that those commands can use either relative or absolute coordinates depending on the command.
However, I also want easy ways to fillet or chamfer corners, tangent align an arc to another line or arc and so on.
Some thoughts:
- Shape generator gives me a points list or a polygon.
- All points to be calculated without the use of boolean construction.
- Commands need to be high level. A render step is required at the end.
- Didn't think about constraints much but edges could be named and referenced.
Consider this shape:
The code could look like this compliant with JSCAD Conventions... which states function parameters should be passed as a JSON object.
var boxWidth = 50;
var boxLength = 100;
var boxHeight = 40;
var boxCut = 15;
var boxRadius = 30;
// Sets start point and global fillet parameter for all edge joins
Shape.init({point:[3,4], fillet:2});
// move to point relative from the init point and fillet that corner with given value
Shape.move({point:[-boxWidth/2,-boxHeight/2], fillet:6});
// draws vertically along y axis by given distance and chamfer that corner with given value
Shape.vert({dist:boxWidth, chamfer:6});
// draws horizontally along y axis by given distance
Shape.horz({dist:boxLength - 15});
// draws an arc tangential to the previous edge to given point with given radius. Other parameters can modify that behavior.
Shape.arc ({point:[15,15], radius: boxRadius});
// draws vertically along y axis by given distance and chamfer that corner with given value
Shape.vert({d:-boxWidth + 15});
var boxPolygon = polygon(Shape.points);
//or
var boxPolygon = Shape.polygon;
The "JSCAD Conventions..." cause us to loose Autocomplete and code suggestion in our editors though. But as we use JSON notation we might as well do the whole thing like that.
var boxWidth = 50;
var boxLength = 100;
var boxHeight = 40;
var boxCut = 15;
var boxRadius = 30;
Shape.steps = [
{ c: 'start', point:[0,0], fillet:2 },
{ c: 'move', point:[-boxWidth/2,-boxHeight/2], fillet:6 },
{ c: 'vert', dist:boxWidth, chamfer:6 },
{ c: 'horz', dist:boxLength - boxCut },
{ c: 'arc', point:[boxCut,-boxCut], r: boxRadius },
{ c: 'vert', dist: -boxWidth + boxCut}
]
var boxPolygon = polygon(Shape.points);
//or
var boxPolygon = Shape.polygon;
Of course now you loose even more of the editors autocomplete logic. But it's clean and very versatile.
Essentially the command list represents the edges of the shape. From here we can even start to look at edge fillet etc.
Note: A fillet cuts into the corner while an arc starts and ends at a precise coordinate.
The shape generator should also have turtle like behavior such as
Shape.turn({angle: 20}); // turns relative to the current direction
Shape.Turn({angle:20}); // sets current direction to angle value
Shape.forward({dist:25}); // draws line in current direction
//Capitalization of a command determines relative or absolute behavior where sensible.
Not even sure if code like this should be an external library of incorporated in JSCAD.
I love to hear what you guys think of the whole shape generator thing.