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