diff --git a/src/along_with.scad b/src/along_with.scad index 7f1748ce..61a74fe8 100644 --- a/src/along_with.scad +++ b/src/along_with.scad @@ -11,6 +11,11 @@ include <__private__/__angy_angz.scad>; include <__private__/__is_vector.scad>; include <__private__/__to3d.scad>; +include <__private__/__m_multiply.scad>; + +// Becuase of improving the performance, this module requires m_rotation.scad which doesn't require in dotSCAD 1.0. +// For backward compatibility, I directly include m_rotation here. +include ; module along_with(points, angles, twist = 0, scale = 1.0) { leng_points = len(points); @@ -27,7 +32,44 @@ module along_with(points, angles, twist = 0, scale = 1.0) { (scale[1] - 1) / leng_points_minus_one, scale[2] == undef ? 0 : (scale[2] - 1) / leng_points_minus_one ] : scale_step(); + + // get rotation matrice for sections + + function local_ang_vects(j) = + j == 0 ? [] : local_ang_vects_sub(j); + function local_ang_vects_sub(j) = + let( + vt0 = points[j] - points[j - 1], + vt1 = points[j + 1] - points[j], + a = acos((vt0 * vt1) / (norm(vt0) * norm(vt1))), + v = cross(vt0, vt1) + ) + concat([[a, v]], local_ang_vects(j - 1)); + + function cumulated_rot_matrice(i, rot_matrice) = + let( + leng_rot_matrice = len(rot_matrice), + leng_rot_matrice_minus_one = leng_rot_matrice - 1, + leng_rot_matrice_minus_two = leng_rot_matrice - 2 + ) + i == leng_rot_matrice - 2 ? + [ + rot_matrice[leng_rot_matrice_minus_one], + __m_multiply(rot_matrice[leng_rot_matrice_minus_two], rot_matrice[leng_rot_matrice_minus_one]) + ] + : cumulated_rot_matrice_sub(i, rot_matrice); + + function cumulated_rot_matrice_sub(i, rot_matrice) = + let( + matrice = cumulated_rot_matrice(i + 1, rot_matrice), + curr_matrix = rot_matrice[i], + prev_matrix = matrice[len(matrice) - 1] + ) + concat(matrice, [__m_multiply(curr_matrix, prev_matrix)]); + + // align modules + module align_with_pts_angles(i) { translate(points[i]) rotate(angles[i]) @@ -45,17 +87,14 @@ module along_with(points, angles, twist = 0, scale = 1.0) { children(0); } - module align_with_pts_local_rotate(j, init_a, init_s) { + module align_with_pts_local_rotate(j, init_a, init_s, cumu_rot_matrice) { if(j == 0) { // first child align_with_pts_init(init_a, init_s) children(0); } else { - vt0 = points[j] - points[j - 1]; - vt1 = points[j + 1] - points[j]; - a = acos((vt0 * vt1) / (norm(vt0) * norm(vt1))); - rotate(a, cross(vt0, vt1)) - align_with_pts_local_rotate(j - 1, init_a, init_s) + multmatrix(cumu_rot_matrice[j - 1]) + align_with_pts_init(init_a, init_s) children(0); } } @@ -72,8 +111,13 @@ module along_with(points, angles, twist = 0, scale = 1.0) { } } else { + cumu_rot_matrice = cumulated_rot_matrice(0, [ + for(ang_vect = local_ang_vects(leng_points - 2)) + m_rotation(ang_vect[0], ang_vect[1]) + ]); + translate(points[0]) - align_with_pts_local_rotate(0, 0, [1, 1, 1]) + align_with_pts_local_rotate(0, 0, [1, 1, 1], cumu_rot_matrice) children(0); if($children == 1) { @@ -90,5 +134,4 @@ module along_with(points, angles, twist = 0, scale = 1.0) { } } } - } \ No newline at end of file