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