1
0
mirror of https://github.com/JustinSDK/dotSCAD.git synced 2025-08-19 13:01:37 +02:00

added bezier_smooth

This commit is contained in:
Justin Lin
2017-05-17 18:02:57 +08:00
parent 93166cb1e4
commit ec9bfb48ff
5 changed files with 141 additions and 0 deletions

View File

@@ -65,6 +65,7 @@ Too many dependencies? Because OpenSCAD doesn't provide namespace management, I
- [circle_path](https://openhome.cc/eGossip/OpenSCAD/lib-circle_path.html)
- [bezier_curve](https://openhome.cc/eGossip/OpenSCAD/lib-bezier_curve.html)
- [bezier_surface](https://openhome.cc/eGossip/OpenSCAD/lib-bezier_surface.html)
- [bezier_smooth](https://openhome.cc/eGossip/OpenSCAD/lib-bezier_smooth.html)
- [helix](https://openhome.cc/eGossip/OpenSCAD/lib-helix.html)
- [golden_spiral](https://openhome.cc/eGossip/OpenSCAD/lib-golden_spiral.html)
- [archimedean_spiral](https://openhome.cc/eGossip/OpenSCAD/lib-archimedean_spiral.html)

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

59
docs/lib-bezier_smooth.md Normal file
View File

@@ -0,0 +1,59 @@
# bezier_smooth
Given a path, the bezier_smooth function uses bazier curves to smooth all corners. You can use it to create smoothier lines or rounded shapes.
Dependencies: the `bezier_curve` function.
## Parameters
- `path_pts` : A list of points represent the path.
- `round_d` : Used to create the other two control points at the corner.
- `t_step` : The distance between two points of the Bézier path at the corner. It defaults to 0.1.
- `closed` : It defaults to `false`. If you have a closed path, set it to `true`.
## Examples
include <hull_polyline3d.scad>;
include <bezier_curve.scad>;
include <bezier_smooth.scad>;
width = 2;
round_d = 15;
path_pts = [
[0, 0, 0],
[40, 60, 10],
[-50, 90, 30],
[-10, -10, 50]
];
hull_polyline3d(
path_pts, width
);
smoothed_path_pts = bezier_smooth(path_pts, round_d);
color("red") translate([30, 0, 0]) hull_polyline3d(
smoothed_path_pts, width
);
![bezier_smooth](images/lib-bezier_smooth-1.JPG)
include <bezier_curve.scad>;
include <bezier_smooth.scad>;
round_d = 10;
path_pts = [
[0, 0],
[40, 0],
[0, 60]
];
polygon(path_pts);
smoothed_path_pts = bezier_smooth(path_pts, round_d, closed = true);
translate([50, 0, 0]) polygon(smoothed_path_pts);
![bezier_smooth](images/lib-bezier_smooth-2.JPG)

81
src/bezier_smooth.scad Normal file
View File

@@ -0,0 +1,81 @@
/**
* bezier_smooth.scad
*
* Given a path, the bezier_smooth function uses bazier curves to smooth all corners.
*
* @copyright Justin Lin, 2017
* @license https://opensource.org/licenses/lgpl-3.0.html
*
* @see https://openhome.cc/eGossip/OpenSCAD/lib-bezier_curve.html
*
**/
include <__private__/__to3d.scad>;
include <__private__/__to2d.scad>;
function _ya_za(p1, p2) =
let(
dx = p2[0] - p1[0],
dy = p2[1] - p1[1],
dz = p2[2] - p1[2],
za = atan2(dy, dx),
ya = atan2(dz, sqrt(pow(dx, 2) + pow(dy, 2)))
) [ya, za];
function _corner_ctrl_pts(round_d, p1, p2, p3) =
let(
_ya_za_1 = _ya_za(p1, p2),
_ya_za_2 = _ya_za(p3, p2),
dz1 = sin(_ya_za_1[0]) * round_d,
dxy1 = cos(_ya_za_1[0]) * round_d,
dy1 = sin(_ya_za_1[1]) * dxy1,
dx1 = cos(_ya_za_1[1]) * dxy1,
dz2 = sin(_ya_za_2[0]) * round_d,
dxy2 = cos(_ya_za_2[0]) * round_d,
dy2 = sin(_ya_za_2[1]) * dxy2,
dx2 = cos(_ya_za_2[1]) * dxy2
)
[
p2 - [dx1, dy1, dz1],
p2,
p2 - [dx2, dy2, dz2]
];
function _bezier_corner(t_step, p1, p2, p3) =
bezier_curve(t_step, _corner_ctrl_pts(round_d, p1, p2, p3));
function _recursive_bezier_smooth(pts, round_d, t_step, leng, i = 0) =
i <= leng - 3 ?
concat(
_bezier_corner(t_step, pts[i], pts[i + 1], pts[i + 2]),
_recursive_bezier_smooth(pts, round_d, t_step, leng, i + 1)
)
: [];
function bezier_smooth(path_pts, round_d, t_step = 0.1, closed = false) =
let(
pts = len(path_pts[0]) == 3 ? path_pts : [for(p = path_pts) __to3d(p)],
leng = len(pts),
middle_pts = _recursive_bezier_smooth(pts, round_d, t_step, leng),
pth_pts = closed ?
concat(
_recursive_bezier_smooth(
[pts[leng - 1], pts[0], pts[1]],
round_d, t_step, 3
),
middle_pts,
_recursive_bezier_smooth(
[pts[leng - 2], pts[leng - 1], pts[0]],
round_d, t_step, 3
)
) :
concat(
[pts[0]],
middle_pts,
[pts[leng - 1]]
)
)
len(path_pts[0]) == 2 ? [for(p = pth_pts) __to2d(p)] : pth_pts;