Skip to content

Instantly share code, notes, and snippets.

@ochafik
Last active March 15, 2022 00:11
Show Gist options
  • Select an option

  • Save ochafik/423310bb408bf90681af19066e0394fe to your computer and use it in GitHub Desktop.

Select an option

Save ochafik/423310bb408bf90681af19066e0394fe to your computer and use it in GitHub Desktop.
Bezier Turtle for BOSL2 / OpenSCAD
// Copyright 2021 Google LLC.
// SPDX-License-Identifier: Apache-2.0
include <BOSL2/std.scad>
include <BOSL2/beziers.scad>
include <BOSL2/turtle3d.scad>
debug=true;
bezier=true;
function bezier_turtle_parse_subcommand(
args,
turtle=[],
control_turtles=[]) =
len(args) == 0
? [turtle, control_turtles]
: args[0] == "ctl" && len(args) > 1
? bezier_turtle_parse_subcommand(
list_tail(args, 2),
turtle=turtle,
control_turtles=concat(
control_turtles,
[concat(turtle, args[1])]
)
)
: bezier_turtle_parse_subcommand(
list_tail(args, 1),
turtle=concat(turtle, [args[0]]),
control_turtles=control_turtles
);
sub=bezier_turtle_parse_subcommand([
"up",
"ctl", ["move", 10],
"ctl", ["left", "move", -20],
"left", 45
]);
echo(sub[0]);
echo(sub[1]);
function bezier_turtle3d(
args,
state=RIGHT,
turtle=[],
transforms=false) =
len(args) == 0
// ? ["turtle", turtle]
? turtle3d(
turtle,
state=state,
transforms=transforms
)
: args[0] == "bezier" && len(args) > 1
? let(sub=bezier_turtle_parse_subcommand(args[1], turtle=turtle),
end_turtle=sub[0],
control_turtles=sub[1],
start_transforms=turtle3d(turtle, state=state, transforms=true),
end_transforms=turtle3d(end_turtle, state=state, transforms=true),
control_transforms=[
for (t=flatten([control_turtles]))
last(turtle3d(t, state=state, transforms=true))
],
bez_transforms=concat(
//[end_transforms[len(start_transforms)]],
[last(start_transforms)],
control_transforms,
[last(end_transforms)]
),
bez_pts=[for (t=bez_transforms) (t * [0,0,0,1]).xyz],
bez_range=[0:0.1:1],
bez_output=bezier_points(bez_pts, bez_range))
concat(
bez_output,
list_tail(
bezier_turtle3d(
list_tail(args, 2),
state=state,
turtle=end_turtle,
transforms=transforms),
len(end_transforms)-1
)
)
: bezier_turtle3d(
list_tail(args, 1),
state=state,
turtle=concat(turtle, [args[0]]),
transforms=transforms);
pts = bezier_turtle3d(
[
"bezier", [
"ctl", ["move", 2],
"move", 1,
//"ctl", ["right", 20, "move", 2],
//"ctl", ["left", 45, "move", 1],
"left", 45,
"move", 1,
"ctl", ["left", 90, "move", -2],
],
"bezier", [
"left", 90,
"move", 1,
"ctl", ["up", 45, "move", 3],
//"ctl", ["right", 20, "move", 2],
//"ctl", ["left", 45, "move", 1],
"move", 1,
"left", 90,
"move", 1,
],
]
);
echo("pts", pts);
rainbow(pts) move($item) sphere(.05, $fn=12);
stroke(pts, width=0.03, closed=false);
//stroke(bezier_points(pts, [0:0.1:1]), width=0.03, closed=false);
//stroke(pts);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment