Bump - didn't make it to the list.
Ronaldo wrote
I have been playing with sweep.scad to render some simple torus knots:
use <scad-utils/transformations.scad>
use <scad-utils/shapes.scad>
use <scad-utils/linalg.scad>
use <scad-utils/transformations.scad>
use <scad-utils/lists.scad>
use
<sweep.scad>
// geometric data
n = 10; // cord section discretization
d = 20; // cord section radius
m = 30 ; // torus discretization
R = 400; // torus major radius
r = 150; // torus minor radius
torus_knot(1,9);
module torus_knot(p, q) {
function knot(phi) = [ (rcos(qphi) + R)cos(pphi),
(rcos(qphi) + R)sin(pphi),
rsin(qphi) ];
function section() = [ for(i=[0: 360/n: 360]) [dcos(i), dsin(i)] ];
k = max(p,q)m;
path = [ for (i=[0:k]) knot(360(i/k)) ];
path_transforms = construct_transform_path(path, closed);
sweep(section(), path_transforms,true);
}
At first, for some values of p and q, there was some very wild torsions
in the shape of the cord. I happily found a nice patch to sweep.scad
posted by Oskar that constructs torsion minimizing sweep rotations
(see
http://forum.openscad.org/Twisty-problem-with-scad-utils-quot-sweep-quot-td9775.html)
With that patch, the horrible torsions had gone.
However, a small but noticeable torsion remained at the junction between
the start and end
of the cord. I had dug into the sweep.scad code and found that there is a
relative rotation
between the end and start sections which is not compensated by the
minimizing torsion
function. Besides, the closed path solution of the sweep library leaves a
"knee" in
the end-start point due to the difference between the starting and ending
tangents.
So, I recoded the patch Oskar posted trying to overcome both flaws.
function construct_torsion_minimizing_rotations(tangents) =
[ for (i = [0:len(tangents)-2])
rotate_from_to(tangents[i],tangents[i+1])
];
function accumulate_rotations(rotations,acc_=[]) = let(i = len(acc_))
i == len(rotations) ? acc_ :
accumulate_rotations(rotations,
i == 0 ? [rotations[0]] : concat(acc_, [ rotations[i] *
acc_[i-1] ])
);
function rotationZ(ang) =
[[ cos(ang), sin(ang), 0],
[ -sin(ang), cos(ang), 0],
[ 0, 0, 1]];
function tangent_path(path, i, closed) =
i == 0 ?
closed ?
unit(path[1]-path[len(path)-2]):
unit(path[1] - path[0]) :
(i == len(path)-1 ?
closed ?
unit(path[1]-path[len(path)-2]):
unit(path[i] - path[i-1]) :
// 0 < i < len(path)-1
unit(path[i+1]-path[i-1]));
function construct_transform_path(path,closed=false) =
let(
l = len(path),
tangents = [ for (i=[0:l-1]) tangent_path(path, i, closed)],
local_rotations =
construct_torsion_minimizing_rotations(concat([[0,0,1]],tangents)),
rotations = accumulate_rotations(concat(local_rotations)),
v1 = rotations[0][1,0,0],
v2 = rotations[l-1][1,0,0],
ang = acos(v1v2) ((v1[1]-v2[1]) > 0? -1: 1), // torsion angle at
the end
rots = [ if (closed) for(j=[1:l]) rotationZ(ang*j/(l-1)) ]
)
closed?
[ for (i = [0:l-1]) construct_rt(rotations[i] * rots[i], path[i]) ]:
[ for (i = [0:l-1]) construct_rt(rotations[i], path[i]) ];
The code is far from efficient but serves to test a concept.
Its main changes are:
Newly minted Admin - PM me if you need anything, or if I've done something stupid...
Unless specifically shown otherwise above, my contribution is in the Public Domain; to the extent possible under law, I have waived all copyright and related or neighbouring rights to this work. Obviously inclusion of works of previous authors is not included in the above.
View this message in context: http://forum.openscad.org/Minimizing-torsion-sweep-for-closed-paths-tp15813p15880.html
Sent from the OpenSCAD mailing list archive at Nabble.com.