omdl  v1.0
OpenSCAD Mechanical Design Library
common_3d.scad
Go to the documentation of this file.
1 //! Common 3D shapes.
2 /***************************************************************************//**
3  \file
4  \author Roy Allen Sutton
5  \date 2015-2023,2026
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 (Common 3d)
31  \amu_define group_brief (Common 3D shapes.)
32 
33  \amu_include (include/amu/doxyg_init_pd_gds_ipg.amu)
34 *******************************************************************************/
35 
36 //----------------------------------------------------------------------------//
37 // group and macros.
38 //----------------------------------------------------------------------------//
39 
40 /***************************************************************************//**
41  \amu_include (include/amu/doxyg_define_in_parent_open.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 //! A cone.
58 /***************************************************************************//**
59  \param size <decimal-list-2 | decimal> A list [r, h] of decimals
60  or a single decimal for (r=h).
61 
62  \param vr <decimal-list-2 | decimal> A list [rb, rp] of decimals or
63  a single decimal for (rb=rp]. The corner rounding radius.
64 
65  \param center <boolean> Center about origin.
66 
67  \details
68 
69  \amu_eval ( object=cone ${object_ex_diagram_3d} )
70 *******************************************************************************/
71 module cone
72 (
73  size = 1,
74  vr,
75  center = false
76 )
77 {
78  r = defined_e_or(size, 0, size);
79  h = defined_e_or(size, 1, r);
80 
81  vr_b = defined_e_or(vr, 0, vr);
82  vr_p = defined_e_or(vr, 1, vr_b);
83 
84  translate( center==true ? [0, 0, -h/2] : origin3d )
85  if ( is_undef(vr) )
86  {
87  cylinder(h=h, r1=r, r2=0, center=false);
88  }
89  else
90  {
91  hl = sqrt(r*r + h*h);
92 
93  rotate_extrude(angle=360)
94  translate([eps*2-r, 0])
95  difference()
96  {
97  tp = triangle2d_sss2ppp([hl, r*2, hl]);
98 
99  polygon( polygon_round_eve_all_p(tp, vr=[vr_p, vr_b, 0]) );
100  square( size=[r, h], center=false );
101  }
102  }
103 }
104 
105 //! A cuboid with edge, round, or chamfer corners.
106 /***************************************************************************//**
107  \param size <decimal-list-3 | decimal> A list [x, y, z] of decimals
108  or a single decimal for (x=y=z).
109 
110  \param vr <decimal> The corner rounding radius.
111 
112  \param vrm <integer> The radius mode.
113  A 2-bit encoded integer that indicates edge and vertex finish.
114  \em B0 controls edge and \em B1 controls vertex.
115 
116  \param center <boolean> Center about origin.
117 
118  \details
119 
120  \amu_eval ( object=cuboid ${object_ex_diagram_3d} )
121 
122  vrm | Description
123  :---:|:--------------------------------------------
124  0 | round edges with round vertexes
125  1 | chamfer edges with sphere vertexes
126  2 | round edges with chamfer vertexes
127  3 | chamfer edges with chamfer vertexes
128 
129  \note Using \em round replaces all edges with a quarter circle
130  of radius \p vr, inset `[vr, vr]` from the each edge.
131  \note Using \em chamfer replaces all edges with isosceles right
132  triangles with side lengths equal to the corner rounding
133  radius \p vr. Therefore the chamfer length will be
134  `vr * sqrt(2)` at 45 degree angles.
135 *******************************************************************************/
136 module cuboid
137 (
138  size = 1,
139  vr,
140  vrm = 0,
141  center = false
142 )
143 {
144  bx = defined_e_or(size, 0, size);
145  by = defined_e_or(size, 1, bx);
146  bz = defined_e_or(size, 2, by);
147 
148  ef = binary_bit_is(vrm, 0, 0);
149  vf = binary_bit_is(vrm, 1, 0);
150 
151  translate(center==true ? origin3d : [bx/2, by/2, bz/2])
152  if ( is_undef(vr) )
153  {
154  cube([bx, by, bz], center=true);
155  }
156  else
157  {
158  cube([bx, by-vr*2, bz-vr*2], center=true);
159  cube([bx-vr*2, by, bz-vr*2], center=true);
160  cube([bx-vr*2, by-vr*2, bz ], center=true);
161 
162  bv = [bx, by, bz];
163  rot = [[0,0,0], [90,0,90], [90,90,0]];
164 
165  for ( axis = [0:2] )
166  {
167  zo = bv[(axis+2)%3]/2 - vr;
168 
169  for ( x = [1,-1], y = [1,-1] )
170  {
171  rotate( rot[axis] )
172  translate( [x*(bv[axis]/2-vr), y*(bv[(axis+1)%3]/2-vr), 0] )
173  if ( ef )
174  {
175  cylinder( h=zo*2, r=vr, center=true );
176  }
177  else
178  {
179  polyhedron
180  (
181  points =
182  [
183  [-eps,-eps,+zo], [(vr+eps)*x,-eps,+zo], [-eps,(vr+eps)*y,+zo],
184  [-eps,-eps,-zo], [(vr+eps)*x,-eps,-zo], [-eps,(vr+eps)*y,-zo],
185  ],
186  faces = [[0,2,1], [0,1,4,3], [1,2,5,4], [2,0,3,5], [3,4,5]]
187  );
188  }
189  }
190  }
191 
192  for ( x = [1,-1], y = [1,-1], z = [1,-1] )
193  {
194  translate([x*(bx/2-vr), y*(by/2-vr), z*(bz/2-vr)])
195  if ( vf )
196  {
197  sphere(vr);
198  }
199  else
200  {
201  polyhedron
202  (
203  points = [[0,0,0], [vr*x,0,0], [0,vr*y,0], [0,0,vr*z]],
204  faces = [[1,2,3], [0,2,1], [0,3,2], [0,1,3]]
205  );
206  }
207  }
208  }
209 }
210 
211 //! An ellipsoid.
212 /***************************************************************************//**
213  \param size <decimal-list-2 | decimal> A list [r, h] of decimals or a
214  single decimal for (2r=h).
215 
216  \param center <boolean> Center about origin.
217 
218  \details
219 
220  \amu_eval ( object=ellipsoid ${object_ex_diagram_3d} )
221 *******************************************************************************/
222 module ellipsoid
223 (
224  size = 1,
225  center = false
226 )
227 {
228  r = defined_e_or(size, 0, size);
229  d = 2 * r;
230  h = defined_e_or(size, 1, d);
231 
232  translate( center==true ? origin3d : [0, 0, h/2] )
233  if (d == h)
234  {
235  sphere( d=d );
236  }
237  else
238  {
239  scale( [1, 1, h/d] )
240  sphere( d=d );
241  }
242 }
243 
244 //! A sector of an ellipsoid.
245 /***************************************************************************//**
246  \param size <decimal-list-2 | decimal> A list [r, h] of decimals or a
247  single decimal for (2r=h).
248 
249  \param a1 <decimal> The start angle in degrees.
250  \param a2 <decimal> The stop angle in degrees.
251 
252  \param center <boolean> Center about origin.
253 
254  \details
255 
256  \amu_eval ( object=ellipsoid_s ${object_ex_diagram_3d} )
257 *******************************************************************************/
258 module ellipsoid_s
259 (
260  size = 1,
261  a1 = 0,
262  a2 = 0,
263  center = false
264 )
265 {
266  r = defined_e_or(size, 0, size);
267  d = 2 * r;
268  h = defined_e_or(size, 1, d);
269 
270  trx = d/2 * sqrt(2) + 1;
271  try = d/2 * sqrt(2) + 1;
272 
273  pa0 = (4 * a1 + 0 * a2) / 4;
274  pa1 = (3 * a1 + 1 * a2) / 4;
275  pa2 = (2 * a1 + 2 * a2) / 4;
276  pa3 = (1 * a1 + 3 * a2) / 4;
277  pa4 = (0 * a1 + 4 * a2) / 4;
278 
279  if (a2 > a1)
280  {
281  intersection()
282  {
283  ellipsoid(size, center);
284 
285  translate(center==true ? [0,0,-h/2] : origin3d)
286  linear_extrude(height=h)
287  polygon
288  ([
289  origin2d,
290  [trx * cos(pa0), try * sin(pa0)],
291  [trx * cos(pa1), try * sin(pa1)],
292  [trx * cos(pa2), try * sin(pa2)],
293  [trx * cos(pa3), try * sin(pa3)],
294  [trx * cos(pa4), try * sin(pa4)],
295  origin2d
296  ]);
297  }
298  }
299  else
300  {
301  ellipsoid(size, center);
302  }
303 }
304 
305 //! A pyramid with trilateral base formed by four equilateral triangles.
306 /***************************************************************************//**
307  \param size <decimal> The face radius.
308 
309  \param center <boolean> Center about origin.
310 
311  \details
312 
313  \amu_eval ( object=pyramid_t ${object_ex_diagram_3d} )
314 *******************************************************************************/
315 module pyramid_t
316 (
317  size = 1,
318  center = false
319 )
320 {
321  s = defined_e_or(size, 0, size);
322 
323  o = s/2;
324  a = s*sqrt(3)/2;
325 
326  translate(center==true ? origin3d : [0,0,o])
327  polyhedron
328  (
329  points =
330  [
331  [-a, -o, -o],
332  [ a, -o, -o],
333  [ 0, s, -o],
334  [ 0, 0, s]
335  ],
336  faces =
337  [
338  [0, 2, 1],
339  [1, 2, 3],
340  [0, 1, 3],
341  [0, 3, 2]
342  ]
343  );
344 }
345 
346 //! A pyramid with quadrilateral base.
347 /***************************************************************************//**
348  \param size <decimal-list-3 | decimal> A list [x, y, z] of decimals
349  or a single decimal for (x=y=z).
350 
351  \param center <boolean> Center about origin.
352 
353  \details
354 
355  \amu_eval ( object=pyramid_q ${object_ex_diagram_3d} )
356 *******************************************************************************/
357 module pyramid_q
358 (
359  size = 1,
360  center = false
361 )
362 {
363  tw = defined_e_or(size, 0, size)/2;
364  th = defined_e_or(size, 1, tw*2)/2;
365  ph = defined_e_or(size, 2, th*2);
366 
367  translate(center==true ? [0,0,-ph/2] : origin3d)
368  polyhedron
369  (
370  points=
371  [
372  [-tw, -th, 0],
373  [-tw, th, 0],
374  [ tw, th, 0],
375  [ tw, -th, 0],
376  [ 0, 0, ph]
377  ],
378  faces=
379  [
380  [0, 3, 2, 1],
381  [0, 1, 4],
382  [1, 2, 4],
383  [2, 3, 4],
384  [3, 0, 4]
385  ]
386  );
387 }
388 
389 //! A three-dimensional star.
390 /***************************************************************************//**
391  \param size <decimal-list-3 | decimal> A list [l, w, h] of decimals
392  or a single decimal for (size=l=2*w=4*h).
393 
394  \param n <decimal> The number of points.
395 
396  \param half <boolean> Render upper half only.
397 
398  \param center <boolean> Center about origin.
399 
400  \details
401 
402  \amu_eval ( object=star3d ${object_ex_diagram_3d} )
403 *******************************************************************************/
404 module star3d
405 (
406  size = 1,
407  n = 5,
408  half = false,
409  center = false
410 )
411 {
412  l = defined_e_or(size, 0, size);
413  w = defined_e_or(size, 1, l/2);
414  h = defined_e_or(size, 2, w/2);
415 
416  s = h/w / 2*sqrt(2);
417 
418  translate( center==true ? origin3d : [0, 0, h/2] )
419  if (half == true)
420  {
421  difference()
422  {
423  repeat_radial(n=n, angle=true, move=false)
424  scale([1, 1, s])
425  rotate([45, 0, 0])
426  rotate([0, 90, 0])
427  pyramid_q(size=[w, w, l], center=false);
428 
429  translate([0,0,-h/2])
430  cylinder(r=l, h=h, center=true);
431  }
432  }
433  else
434  {
435  repeat_radial(n=n, angle=true, move=false)
436  scale([1, 1, s])
437  rotate([45, 0, 0])
438  rotate([0, 90, 0])
439  pyramid_q(size=[w, w, l], center=false);
440  }
441 }
442 
443 //! @}
444 //! @}
445 
446 //----------------------------------------------------------------------------//
447 // openscad-amu auxiliary scripts
448 //----------------------------------------------------------------------------//
449 
450 /*
451 BEGIN_SCOPE diagram;
452  BEGIN_OPENSCAD;
453  include <omdl-base.scad>;
454 
455  shape = "cone";
456  $fn = 36;
457 
458  if (shape == "cone")
459  cone( [10, 25], vr=2, center=true );
460  else if (shape == "cuboid")
461  cuboid( size=[25,40,20], vr=5, center=true );
462  else if (shape == "ellipsoid")
463  ellipsoid( size=[40,25], center=true );
464  else if (shape == "ellipsoid_s")
465  ellipsoid_s( size=[60,15], a1=0, a2=270, center=true );
466  else if (shape == "pyramid_t")
467  pyramid_t( size=20, center=true );
468  else if (shape == "pyramid_q")
469  pyramid_q( size=[35,20,5], center=true );
470  else if (shape == "star3d")
471  star3d( size=40, n=5, half=true, center=true );
472  END_OPENSCAD;
473 
474  BEGIN_MFSCRIPT;
475  include --path "${INCLUDE_PATH}" {var_init,var_gen_png2eps}.mfs;
476 
477  views name "views" views "diag";
478  defines name "shapes" define "shape"
479  strings "
480  cone
481  cuboid
482  ellipsoid
483  ellipsoid_s
484  pyramid_t
485  pyramid_q
486  star3d
487  ";
488  variables add_opts_combine "views shapes";
489  variables add_opts "--viewall --autocenter --view=axes";
490 
491  include --path "${INCLUDE_PATH}" scr_make_mf.mfs;
492  END_MFSCRIPT;
493 END_SCOPE;
494 */
495 
496 //----------------------------------------------------------------------------//
497 // end of file
498 //----------------------------------------------------------------------------//
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
eps
<decimal> Epsilon, small distance to deal with overlapping shapes.
Definition: constants.scad:195
function binary_bit_is(v, b, t=1)
Test if a binary bit position of an integer value equals a test bit.
function defined_e_or(v, i, d)
Returns an element from an iterable if it exists, or a default value if not.
function polygon_round_eve_all_p(c, vr=0, vrm=1, vfn, w=true, cw=true)
Compute coordinates that round all of the vertices between each adjacent edges in 2D.
function triangle2d_sss2ppp(v, a=x_axis_ci, cw=true)
Compute a set of vertex coordinates for a triangle given its side lengths in 2D.
module pyramid_q(size=1, center=false)
A pyramid with quadrilateral base.
Definition: common_3d.scad:772
module ellipsoid_s(size=1, a1=0, a2=0, center=false)
A sector of an ellipsoid.
Definition: common_3d.scad:663
module star3d(size=1, n=5, half=false, center=false)
A three-dimensional star.
Definition: common_3d.scad:824
module cone(size=1, vr, center=false)
A cone.
Definition: common_3d.scad:461
module cuboid(size=1, vr, vrm=0, center=false)
A cuboid with edge, round, or chamfer corners.
Definition: common_3d.scad:531
module pyramid_t(size=1, center=false)
A pyramid with trilateral base formed by four equilateral triangles.
Definition: common_3d.scad:725
module ellipsoid(size=1, center=false)
An ellipsoid.
Definition: common_3d.scad:622
module repeat_radial(n, r=1, ao=0, angle=true, move=false)
Radially repeat copies of child objects about a z-axis radius.
Definition: repeat.scad:462
function angle(a, from=angle_unit_default, to=angle_unit_base)
Convert an angle value from one unit to another.