omdl  v0.9.8
OpenSCAD Mechanical Design Library
repeat.scad
Go to the documentation of this file.
1 //! Shape repetition tools.
2 /***************************************************************************//**
3  \file
4  \author Roy Allen Sutton
5  \date 2015-2019
6 
7  \copyright
8 
9  This file is part of [omdl] (https://github.com/royasutton/omdl),
10  an OpenSCAD mechanical design library.
11 
12  The \em omdl is free software; you can redistribute it and/or modify
13  it under the terms of the [GNU Lesser General Public License]
14  (http://www.gnu.org/licenses/lgpl.html) as published by the Free
15  Software Foundation; either version 2.1 of the License, or (at
16  your option) any later version.
17 
18  The \em omdl is distributed in the hope that it will be useful,
19  but WITHOUT ANY WARRANTY; without even the implied warranty of
20  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21  Lesser General Public License for more details.
22 
23  You should have received a copy of the GNU Lesser General Public
24  License along with the \em omdl; if not, write to the Free Software
25  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26  02110-1301, USA; or see <http://www.gnu.org/licenses/>.
27 
28  \details
29 
30  \amu_define group_name (Repeat)
31  \amu_define group_brief (Shape repetition tools.)
32 
33  \amu_include (include/amu/pgid_path_pstem_pg.amu)
34 *******************************************************************************/
35 
36 //----------------------------------------------------------------------------//
37 // group and macros.
38 //----------------------------------------------------------------------------//
39 
40 /***************************************************************************//**
41  \amu_include (include/amu/group_in_parent_start.amu)
42  \amu_include (include/amu/includes_required.amu)
43 
44  \amu_define image_view (diag)
45 
46  \amu_define group_id (${parent})
47  \amu_include (include/amu/scope_diagrams_3d_in_group.amu)
48 
49  \amu_define group_id (${group})
50  \amu_include (include/amu/scope_diagrams_3d_in_group.amu)
51 
52  \amu_include (include/amu/scope_diagram_3d_object.amu)
53 *******************************************************************************/
54 
55 //----------------------------------------------------------------------------//
56 
57 //! Radially repeat copies of child objects about a z-axis radius.
58 /***************************************************************************//**
59  \param n <integer> The number of equally spaced radii.
60  \param r <decimal> The radial move distance.
61  \param o <decimal> The rotational angular offset.
62  \param angle <boolean> Rotate each copy about z-axis.
63  \param move <boolean> Move each shape copy to radii coordinate.
64 
65  \details
66 
67  All child objects are repeated together \p n times about the z-axis
68  at radius \p r.
69 
70  \amu_eval ( object=repeat_radial ${object_ex_diagram_3d} )
71 *******************************************************************************/
72 module repeat_radial
73 (
74  n,
75  r = 1,
76  o = 0,
77  angle = true,
78  move = false
79 )
80 {
81  if (n > 0)
82  {
83  for ( p = polygon_regular_p( n=n, r=r, o=o ) )
84  {
85  translate(move==true ? p : origin2d)
86  rotate(angle==true ? [0, 0, angle_ll(x_axis2d_uv, p)] : origin3d)
87  children();
88  }
89  }
90 }
91 
92 //! Repeat copies of child objects about a Cartesian grid.
93 /***************************************************************************//**
94  \param g <integer-list-3 | integer> The grid division count. A list
95  [x, y, z] of integers or a single integer for (x=y=z).
96  \param i <decimal-list-3 | decimal> The grid increment size. A list
97  [x, y, z] of decimals or a single decimal for (x=y=z).
98  \param c <integer> The number of copies. Number of times to iterate
99  over children.
100  \param center <boolean> Center distribution about origin.
101 
102  \details
103 
104  The child objects are repeated individually \p c times about the
105  grid \p g with grid spacing increments \p i.
106 
107  \warning Only immediate children are handled individually as shown
108  in the following example. Children that are produced by
109  intermediate operation, such as object generated by a for
110  loop, will be treated as a single child object.
111 
112  \amu_eval ( object=repeat_grid ${object_ex_diagram_3d} )
113 *******************************************************************************/
114 module repeat_grid
115 (
116  g,
117  i,
118  c = 1,
119  center = false
120 )
121 {
122  gridd = is_scalar(g) ? g : 1;
123 
124  gridx = defined_e_or(g, 0, gridd);
125  gridy = defined_e_or(g, 1, gridd);
126  gridz = defined_e_or(g, 2, gridd);
127 
128  incrd = is_scalar(i) ? i : 0;
129 
130  incrx = defined_e_or(i, 0, incrd);
131  incry = defined_e_or(i, 1, incrd);
132  incrz = defined_e_or(i, 2, incrd);
133 
134  // check grid capacity against child objects
135  if ( ( $children * c ) > ( gridx * gridy * gridz ) )
136  {
137  log_warn("more objects than grid capacity, shapes will overlap.");
138  log_info
139  (
140  str
141  (
142  "children=", $children,
143  ", copies=", c,
144  ", objects=", $children * c
145  )
146  );
147  log_info
148  (
149  str
150  (
151  "grid[x,y,z]=[", gridx, ", ", gridy, ", ", gridz, "]",
152  ", capacity=", gridx * gridy * gridz
153  )
154  );
155  }
156 
157  translate
158  (
159  center==true
160  ? [
161  -( min($children * c, gridx) -1 ) * incrx / 2,
162  -( min(ceil($children * c/gridx), gridy) -1 ) * incry / 2,
163  -( min(ceil($children * c/gridx/gridy), gridz) -1 ) * incrz / 2
164  ]
165  : origin3d
166  )
167  if ( c > 0 )
168  {
169  for
170  (
171  y = [0 : (c-1)],
172  x = [0 : ($children-1)]
173  )
174  {
175  j = y * $children + x;
176 
177  translate
178  (
179  [
180  incrx * (j%gridx),
181  incry * (floor(j/gridx)%gridy),
182  incrz * (floor(floor(j/gridx)/gridy)%gridz)
183  ]
184  )
185  children([x]);
186  }
187  }
188 }
189 
190 //! @}
191 //! @}
192 
193 //----------------------------------------------------------------------------//
194 // openscad-amu auxiliary scripts
195 //----------------------------------------------------------------------------//
196 
197 /*
198 BEGIN_SCOPE diagram;
199  BEGIN_OPENSCAD;
200  include <omdl-base.scad>;
201 
202  shape = "repeat_radial";
203  $fn = 36;
204 
205  if (shape == "repeat_radial")
206  repeat_radial( n=7, r=6, move=true ) square( [20,1], center=true );
207  else if (shape == "repeat_grid")
208  repeat_grid( g=[5,5,4], i=10, c=50, center=true ) {cube(10, center=true); sphere(10);}
209  END_OPENSCAD;
210 
211  BEGIN_MFSCRIPT;
212  include --path "${INCLUDE_PATH}" {var_init,var_gen_png2eps}.mfs;
213 
214  views name "views" views "diag";
215  defines name "shapes" define "shape"
216  strings "
217  repeat_radial
218  repeat_grid
219  ";
220  variables add_opts_combine "views shapes";
221  variables add_opts "--viewall --autocenter --view=axes";
222 
223  include --path "${INCLUDE_PATH}" scr_make_mf.mfs;
224  END_MFSCRIPT;
225 END_SCOPE;
226 */
227 
228 //----------------------------------------------------------------------------//
229 // end of file
230 //----------------------------------------------------------------------------//
module log_warn(m)
Output warning message to console.
Definition: console.scad:333
module log_info(m)
Output information message to console.
Definition: console.scad:318
origin2d
<point-2d> The origin point coordinate in 2d Euclidean space.
Definition: constants.scad:407
origin3d
<point-3d> The origin point coordinate in 3-dimensional Euclidean space.
Definition: constants.scad:425
x_axis2d_uv
<vector-2d> The unit vector of the positive x-axis in 2d Euclidean space.
Definition: constants.scad:410
function angle_ll(l1, l2, s=true)
Compute the angle between two lines or vectors in a 3d or 2d-space.
function defined_e_or(v, i, d)
Return an element of an iterable when it exists or a default value otherwise.
function is_scalar(v)
Test if a value is a single non-iterable value.
function polygon_regular_p(n, r, a, c=origin2d, o=0, vr, cw=true)
Compute coordinates for an n-sided regular polygon in 2D.
module repeat_radial(n, r=1, o=0, angle=true, move=false)
Radially repeat copies of child objects about a z-axis radius.
Definition: repeat.scad:462
module repeat_grid(g, i, c=1, center=false)
Repeat copies of child objects about a Cartesian grid.
Definition: repeat.scad:509
function angle(a, from=angle_unit_default, to=angle_unit_base)
Convert an angle from some units to another.