omdl  v0.5
OpenSCAD Mechanical Design Library
shapes2d.scad
Go to the documentation of this file.
1 //! Two-dimensional basic shapes.
2 /***************************************************************************//**
3  \file shapes2d.scad
4  \author Roy Allen Sutton
5  \date 2015-2017
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  \ingroup shapes shapes_2d
31 *******************************************************************************/
32 
33 include <transform.scad>;
34 
35 //----------------------------------------------------------------------------//
36 /***************************************************************************//**
37  \addtogroup shapes
38  @{
39 
40  \amu_define caption (2D Shapes)
41 
42  \amu_make png_files (append=dim extension=png)
43  \amu_make eps_files (append=dim extension=png2eps)
44  \amu_shell file_cnt ("echo ${png_files} | wc -w")
45  \amu_shell cell_num ("seq -f '(%g)' -s '^' ${file_cnt}")
46 
47  \htmlonly
48  \amu_image_table
49  (
50  type=html columns=4 image_width="200" cell_files="${png_files}"
51  table_caption="${caption}" cell_captions="${cell_num}"
52  )
53  \endhtmlonly
54  \latexonly
55  \amu_image_table
56  (
57  type=latex columns=4 image_width="1.25in" cell_files="${eps_files}"
58  table_caption="${caption}" cell_captions="${cell_num}"
59  )
60  \endlatexonly
61 
62  \defgroup shapes_2d 2D Shapes
63  \brief Two dimensional geometric shapes.
64  @{
65 *******************************************************************************/
66 //----------------------------------------------------------------------------//
67 
68 //----------------------------------------------------------------------------//
69 // amu macros
70 //----------------------------------------------------------------------------//
71 /***************************************************************************//**
72  \amu_define scope (shapes2d_dim)
73  \amu_define tuple (qvga_top)
74 
75  \amu_define example_dim
76  (
77  \image html ${scope}_${tuple}_${function}.png "${function}"
78  \image latex ${scope}_${tuple}_${function}.eps "${function}" width=2.5in
79  \dontinclude ${scope}.scad \skipline ${function}(
80  )
81 *******************************************************************************/
82 //----------------------------------------------------------------------------//
83 
84 //! A rectangle with edge, fillet, and/or chamfer corners.
85 /***************************************************************************//**
86  \param size <vector|decimal> A vector [x, y] of decimals
87  or a single decimal for (x=y).
88 
89  \param vr <vector|decimal> The corner rounding radius.
90  A vector [v1r, v2r, v3r, v4r] of decimals or a single decimal
91  for (v1r=v2r=v3r=v4r). Unspecified corners are not rounded.
92 
93  \param vrm <integer> The corner radius mode.
94  A 4-bit encoded integer that indicates each corner finish.
95  Use bit value \b 0 for \em fillet and \b 1 for \em chamfer.
96 
97  \param center <boolean> Center about origin.
98 
99  \details
100 
101  \b Example
102  \amu_eval ( function=rectangle ${example_dim} )
103 
104  \note A corner \em fillet replaces an edge with a quarter circle of
105  radius \p vr, inset <tt>[vr, vr]</tt> from the corner vertex.
106  \note A corner \em chamfer replaces an edge with an isosceles right
107  triangle with side lengths equal to the corresponding corner
108  rounding radius \p vr. Therefore the chamfer length will be
109  <tt>vr*sqrt(2)</tt> at 45 degree angles.
110 *******************************************************************************/
111 module rectangle
112 (
113  size,
114  vr,
115  vrm = 0,
116  center = false
117 )
118 {
119  rx = edefined_or(size, 0, size);
120  ry = edefined_or(size, 1, rx);
121 
122  translate(center==true ? [-rx/2, -ry/2] : origin2d)
123  {
124  if ( not_defined(vr) ) // no rounding
125  {
126  square([rx, ry]);
127  }
128  else if ( is_scalar(vr) ) // equal rounding
129  {
130  for ( i = [ [0, 0, 1, 0, 1, 0],
131  [1, 1, -1, 0, 1, 90],
132  [2, 1, -1, 1, -1, 180],
133  [3, 0, 1, 1, -1, 270] ] )
134  {
135  translate([rx*i[1] + vr * i[2], ry*i[3] + vr * i[4]])
136  if ( bitwise_is_equal(vrm, i[0], 0) )
137  {
138  circle(r=vr);
139  }
140  else
141  {
142  rotate([0, 0, i[5]])
143  polygon(points=[[eps,-vr], [eps,eps], [-vr,eps]], paths=[[0,1,2]]);
144  }
145  }
146 
147  translate([0, vr])
148  square([rx, ry] - [0, vr*2]);
149 
150  translate([vr, 0])
151  square([rx, ry] - [vr*2, 0]);
152  }
153  else // individual rounding
154  {
155  crv = [ edefined_or(vr, 0, 0),
156  edefined_or(vr, 1, 0),
157  edefined_or(vr, 2, 0),
158  edefined_or(vr, 3, 0) ];
159 
160  for ( i = [ [0, 0, 1, 0, 1],
161  [1, 1, -1, 0, 1],
162  [2, 1, -1, 1, -1],
163  [3, 0, 1, 1, -1] ] )
164  {
165  if ( (crv[i[0]] > 0) && bitwise_is_equal(vrm, i[0], 0) )
166  {
167  translate([rx*i[1] + crv[i[0]] * i[2], ry*i[3] + crv[i[0]] * i[4]])
168  circle(r=crv[i[0]]);
169  }
170  }
171 
172  ppv =
173  [
174  for
175  (
176  i = [
177  [0, 0, 0, 0, 1],
178  [0, 0, 1, 0, 0],
179  [1, 1, -1, 0, 0],
180  [1, 1, 0, 0, 1],
181  [2, 1, 0, 1, -1],
182  [2, 1, -1, 1, 0],
183  [3, 0, 1, 1, 0],
184  [3, 0, 0, 1, -1]
185  ]
186  )
187  [rx*i[1] + crv[i[0]] * i[2], ry*i[3] + crv[i[0]] * i[4]]
188  ];
189 
190  polygon( points=ppv, paths=[ [0,1,2,3,4,5,6,7] ] );
191  }
192  }
193 }
194 
195 //! A rectangle with a removed rectangular core.
196 /***************************************************************************//**
197  \param size <vector|decimal> A vector [x, y] of decimals
198  or a single decimal for (x=y).
199  \param core <vector|decimal> A vector [x, y] of decimals
200  or a single decimal for (x=y).
201 
202  \param t <vector|decimal> A vector [x, y] of decimals
203  or a single decimal for (x=y).
204 
205  \param co <vector> Core offset. A vector [x, y] of decimals.
206  \param cr <decimal> Core z-rotation.
207 
208  \param vr <vector|decimal> The default corner rounding radius.
209  A vector [v1r, v2r, v3r, v4r] of decimals or a single decimal
210  for (v1r=v2r=v3r=v4r). Unspecified corners are not rounded.
211  \param vr1 <vector|decimal> The outer corner rounding radius.
212  \param vr2 <vector|decimal> The core corner rounding radius.
213 
214  \param vrm <integer> The default corner radius mode.
215  A 4-bit encoded integer that indicates each corner finish.
216  Use bit value \b 0 for \em fillet and \b 1 for \em chamfer.
217  \param vrm1 <integer> The outer corner radius mode.
218  \param vrm2 <integer> The core corner radius mode.
219 
220  \param center <boolean> Center about origin.
221 
222  \details
223 
224  Thickness \p t
225  \li <tt>core = size - t</tt>; when \p t and \p size are given.
226  \li <tt>size = core + t</tt>; when \p t and \p core are given.
227 
228  \b Example
229  \amu_eval ( function=rectangle_c ${example_dim} )
230 *******************************************************************************/
231 module rectangle_c
232 (
233  size,
234  core,
235  t,
236  co,
237  cr = 0,
238  vr,
239  vr1,
240  vr2,
241  vrm = 0,
242  vrm1,
243  vrm2,
244  center = false
245 )
246 {
247  rx = edefined_or(size, 0, size);
248  ry = edefined_or(size, 1, rx);
249 
250  od = all_defined([t, core]) ? (core + t) : size;
251  id = all_defined([t, size]) ? (size - t) : core;
252 
253  or = defined_or(vr1, vr);
254  ir = defined_or(vr2, vr);
255 
256  om = defined_or(vrm1, vrm);
257  im = defined_or(vrm2, vrm);
258 
259  if ( is_defined(id) )
260  {
261  translate(center==true ? origin2d : [rx/2, ry/2])
262  difference()
263  {
264  rectangle(size=od, vr=or, vrm=om, center=true);
265 
266  translate(is_defined(co) ? co : origin2d)
267  rotate([0, 0, cr])
268  rectangle(size=id, vr=ir, vrm=im, center=true);
269  }
270  }
271  else
272  {
273  rectangle(size=od, vr=or, vrm=om, center=center);
274  }
275 }
276 
277 //! A rhombus.
278 /***************************************************************************//**
279  \param size <vector|decimal> A vector [w, h] of decimals
280  or a single decimal for (w=h).
281 
282  \param vr <vector|decimal> The corner rounding radius.
283  A vector [v1r, v2r, v3r, v4r] of decimals or a single decimal
284  for (v1r=v2r=v3r=v4r). Unspecified corners are not rounded.
285 
286  \param center <boolean> Center about origin.
287 
288  \details
289 
290  \b Example
291  \amu_eval ( function=rhombus ${example_dim} )
292 
293  See [Wikipedia](https://en.wikipedia.org/wiki/Rhombus)
294  for more information.
295 *******************************************************************************/
296 module rhombus
297 (
298  size,
299  vr,
300  center = false
301 )
302 {
303  rx = edefined_or(size, 0, size) / 2;
304  ry = edefined_or(size, 1, rx*2) / 2;
305 
306  translate(center==true ? origin2d : [rx, ry])
307  {
308  if ( not_defined(vr) ) // no rounding
309  {
310  polygon
311  (
312  points=[ [rx,0], [0,ry], [-rx,0], [0,-ry] ],
313  paths=[ [0,1,2,3] ]
314  );
315  }
316  else // individual rounding
317  {
318  erc = is_scalar(vr) ? vr : 0; // equal rounding
319 
320  crv = [ edefined_or(vr, 0, erc),
321  edefined_or(vr, 1, erc),
322  edefined_or(vr, 2, erc),
323  edefined_or(vr, 3, erc) ];
324 
325  a1 = angle_vv(v1t=[0,ry], v1i=[rx,0], v2t=[0,-ry], v2i=[rx,0]) / 2;
326  a2 = 90 - a1;
327 
328  for ( i = [ [0, 1, -1, 0, 0],
329  [1, 0, 0, 1, -1],
330  [2, -1, 1, 0, 0],
331  [3, 0, 0, -1, 1] ] )
332  {
333  translate
334  (
335  [ rx*i[1] + crv[i[0]]/sin(a1) * i[2], ry*i[3] + crv[i[0]]/sin(a2) * i[4] ]
336  )
337  circle (r=crv[i[0]]);
338  }
339 
340  ppv =
341  [
342  for
343  (
344  i = [
345  [0, 0, 1, -1, 0, -1],
346  [0, 0, 1, -1, 0, 1],
347  [1, 1, 0, 1, 1, -1],
348  [1, 1, 0, -1, 1, -1],
349  [2, 0, -1, 1, 0, 1],
350  [2, 0, -1, 1, 0, -1],
351  [3, 1, 0, -1, -1, 1],
352  [3, 1, 0, +1, -1, +1]
353  ]
354  )
355  ( i[1] == 0 )
356  ? [
357  rx*i[2] + crv[i[0]] * (1/sin(a1)-sin(a1)) * i[3],
358  ry*i[4] + crv[i[0]] * cos(a1) * i[5]
359  ]
360  : [
361  rx*i[2] + crv[i[0]] * cos(a2) * i[3],
362  ry*i[4] + crv[i[0]] * (1/sin(a2)-sin(a2)) * i[5]
363  ]
364  ];
365 
366  polygon( points=ppv, paths=[ [0,1,2,3,4,5,6,7] ] );
367  }
368  }
369 }
370 
371 //! A general triangle specified by three vertices.
372 /***************************************************************************//**
373  \param v1 <vector> A vector [x, y] for vertex 1.
374  \param v2 <vector> A vector [x, y] for vertex 2.
375  \param v3 <vector> A vector [x, y] for vertex 3.
376 
377  \param vr <decimal> The default vertex rounding radius.
378  \param v1r <decimal> Vertex 1 rounding radius.
379  \param v2r <decimal> Vertex 2 rounding radius.
380  \param v3r <decimal> Vertex 3 rounding radius.
381 
382  \param centroid <boolean> Center centroid at origin.
383  \param incenter <boolean> Center incenter at origin.
384 
385  \details
386 
387  \b Example
388  \amu_eval ( function=triangle_ppp ${example_dim} )
389 
390  \warning Currently, in order to round any vertex, all must be given
391  a rounding radius, either via \p vr or individually.
392 
393  \todo Replace the hull() operation with calculated tangential
394  intersection of the rounded vertexes.
395  \todo Remove the all or nothing requirement for vertex rounding.
396 *******************************************************************************/
397 module triangle_ppp
398 (
399  v1,
400  v2,
401  v3,
402  vr,
403  v1r,
404  v2r,
405  v3r,
406  centroid = false,
407  incenter = false
408 )
409 {
410  cr1 = defined_or(v1r, vr);
411  cr2 = defined_or(v2r, vr);
412  cr3 = defined_or(v3r, vr);
413 
414  translate
415  (
416  ( centroid==false ) && ( incenter==true )
417  ? -triangle_incenter_ppp( v1=v1, v2=v2, v3=v3 )
418  : origin2d
419  )
420  translate
421  (
422  ( centroid==true ) && ( incenter==false )
423  ? -triangle_centroid_ppp( v1=v1, v2=v2, v3=v3 )
424  : origin2d
425  )
426  if ( any_undefined([cr1, cr2, cr3]) )
427  {
428  polygon( points=[v1, v2, v3], paths=[[0,1,2]] );
429  }
430  else
431  {
432  ic = triangle_incenter_ppp( v1=v1, v2=v2, v3=v3 );
433 
434  a1 = angle_vv(v1t=v2, v1i=v1, v2t=ic, v2i=v1);
435  a2 = angle_vv(v1t=v3, v1i=v2, v2t=ic, v2i=v2);
436  a3 = angle_vv(v1t=v1, v1i=v3, v2t=ic, v2i=v3);
437 
438  c1 = v1 + cr1/sin(a1) * unit_v(vt=ic, vi=v1);
439  c2 = v2 + cr2/sin(a2) * unit_v(vt=ic, vi=v2);
440  c3 = v3 + cr3/sin(a3) * unit_v(vt=ic, vi=v3);
441 
442  hull()
443  {
444  translate( c1 )
445  circle( r=cr1 );
446  translate( c2 )
447  circle( r=cr2 );
448  translate( c3 )
449  circle( r=cr3 );
450  }
451  }
452 }
453 
454 //! A general triangle specified by a vector of its three vertices.
455 /***************************************************************************//**
456  \param v <vector> A vector [v1, v2, v3] of vectors [x, y].
457 
458  \param vr <vector|decimal> The vertex rounding radius. A vector
459  [v1r, v2r, v3r] of decimals or a single decimal for (v1r=v2r=v3r).
460 
461  \param centroid <boolean> Center centroid at origin.
462  \param incenter <boolean> Center incenter at origin.
463 
464  \details
465 
466  \b Example
467  \code{.C}
468  t = triangle_lll2vp( 30, 40, 50 );
469  r = [2, 4, 6];
470  triangle_vp( v=t, vr=r );
471  \endcode
472 *******************************************************************************/
473 module triangle_vp
474 (
475  v,
476  vr,
477  centroid = false,
478  incenter = false
479 )
480 {
481  if ( is_scalar(vr) )
482  {
484  (
485  v1=v[0], v2=v[1], v3=v[2],
486  vr=vr,
487  centroid=centroid, incenter=incenter
488  );
489  }
490  else
491  {
493  (
494  v1=v[0], v2=v[1], v3=v[2],
495  v1r=vr[0], v2r=vr[1], v3r=vr[2],
496  centroid=centroid, incenter=incenter
497  );
498  }
499 }
500 
501 //! A general triangle specified by its three side lengths.
502 /***************************************************************************//**
503  \param s1 <decimal> The length of the side 1 (along the x-axis).
504  \param s2 <decimal> The length of the side 2.
505  \param s3 <decimal> The length of the side 3.
506 
507  \param vr <decimal> The default vertex rounding radius.
508  \param v1r <decimal> Vertex 1 rounding radius.
509  \param v2r <decimal> Vertex 2 rounding radius.
510  \param v3r <decimal> Vertex 3 rounding radius.
511 
512  \param centroid <boolean> Center centroid at origin.
513  \param incenter <boolean> Center incenter at origin.
514 
515  \details
516 
517  \b Example
518  \amu_eval ( function=triangle_lll ${example_dim} )
519 
520  See [Wikipedia](https://en.wikipedia.org/wiki/Solution_of_triangles)
521  for more information.
522 *******************************************************************************/
523 module triangle_lll
524 (
525  s1,
526  s2,
527  s3,
528  vr,
529  v1r,
530  v2r,
531  v3r,
532  centroid = false,
533  incenter = false
534 )
535 {
536  a1 = acos( (s2*s2 + s3*s3 - s1*s1) / (2 * s2 * s3) );
537  a2 = acos( (s1*s1 + s3*s3 - s2*s2) / (2 * s1 * s3) );
538  a3 = 180 - a1 - a2;
539 
540  p3 = [s2*cos(a3), s2*sin(a3)];
541 
542  if ( is_nan( p3[0] ) || is_nan( p3[1] ) )
543  {
544  log_warn
545  (
546  str( "can not render triangle with sides (", s1, ", ", s2, ", ", s3, ")" )
547  );
548  }
549  else
550  {
551  v1 = origin2d;
552  v2 = [s1, 0];
553  v3 = [s1 - p3[0], p3[1]];
554 
556  (
557  v1=v1, v2=v2, v3=v3,
558  vr=vr, v1r=v1r, v2r=v2r, v3r=v3r,
559  centroid=centroid, incenter=incenter
560  );
561  }
562 }
563 
564 //! A general triangle specified by a vector of its three side lengths.
565 /***************************************************************************//**
566  \param v <vector> A vector [s1, s2, s3] of decimals.
567 
568  \param vr <vector|decimal> The vertex rounding radius. A vector
569  [v1r, v2r, v3r] of decimals or a single decimal for (v1r=v2r=v3r).
570 
571  \param centroid <boolean> Center centroid at origin.
572  \param incenter <boolean> Center incenter at origin.
573 
574  \details
575 
576  \b Example
577  \code{.C}
578  t = triangle_lll2vp( 3, 4, 5 );
579  s = triangle_vp2vl( t );
580  triangle_vl( v=s, vr=2, centroid=true );
581  \endcode
582 *******************************************************************************/
583 module triangle_vl
584 (
585  v,
586  vr,
587  centroid = false,
588  incenter = false
589 )
590 {
591  if ( is_scalar(vr) )
592  {
594  (
595  s1=v[0], s2=v[1], s3=v[2],
596  vr=vr,
597  centroid=centroid, incenter=incenter
598  );
599  }
600  else
601  {
603  (
604  s1=v[0], s2=v[1], s3=v[2],
605  v1r=vr[0], v2r=vr[1], v3r=vr[2],
606  centroid=centroid, incenter=incenter
607  );
608  }
609 }
610 
611 //! A general triangle specified by its sides with a removed triangular core.
612 /***************************************************************************//**
613  \param vs <vector|decimal> The size. A vector [s1, s2, s3] of decimals
614  or a single decimal for (s1=s2=s3).
615  \param vc <vector|decimal> The core. A vector [s1, s2, s3] of decimals
616  or a single decimal for (s1=s2=s3).
617 
618  \param co <vector> Core offset. A vector [x, y] of decimals.
619  \param cr <decimal> Core z-rotation.
620 
621  \param vr <vector|decimal> The default vertex rounding radius. A vector
622  [v1r, v2r, v3r] of decimals or a single decimal for (v1r=v2r=v3r).
623  \param vr1 <vector|decimal> The outer vertex rounding radius.
624  \param vr2 <vector|decimal> The core vertex rounding radius.
625 
626  \param centroid <boolean> Center centroid at origin.
627  \param incenter <boolean> Center incenter at origin.
628 
629  \details
630 
631  \b Example
632  \amu_eval ( function=triangle_vl_c ${example_dim} )
633 
634  \note The outer and inner triangles centroids are aligned prior to
635  the core removal.
636 *******************************************************************************/
637 module triangle_vl_c
638 (
639  vs,
640  vc,
641  co,
642  cr = 0,
643  vr,
644  vr1,
645  vr2,
646  centroid = false,
647  incenter = false
648 )
649 {
650  ts1 = edefined_or(vs, 0, vs);
651  ts2 = edefined_or(vs, 1, ts1);
652  ts3 = edefined_or(vs, 2, ts2);
653 
654  tc1 = edefined_or(vc, 0, vc);
655  tc2 = edefined_or(vc, 1, tc1);
656  tc3 = edefined_or(vc, 2, tc2);
657 
658  vrs = defined_or(vr1, vr);
659  vrc = defined_or(vr2, vr);
660 
661  if ( is_defined(vc) )
662  {
663  translate
664  (
665  ( centroid==false ) && ( incenter==true )
666  ? -triangle_incenter_vp( triangle_lll2vp(s1=ts1, s2=ts2, s3=ts3) )
667  : origin2d
668  )
669  translate
670  (
671  ( centroid==true ) && ( incenter==false )
672  ? origin2d
673  : triangle_centroid_vp( triangle_lll2vp(s1=ts1, s2=ts2, s3=ts3) )
674  )
675  difference()
676  {
678  (
679  v=[ts1, ts2, ts3],
680  vr=vrs,
681  centroid=true, incenter=false
682  );
683 
684  translate(is_defined(co) ? co : origin2d)
685  rotate([0, 0, cr])
687  (
688  v=[tc1, tc2, tc3],
689  vr=vrc,
690  centroid=true, incenter=false
691  );
692  }
693  }
694  else
695  {
697  (
698  v=[ts1, ts2, ts3],
699  vr=vrs,
700  centroid=centroid, incenter=incenter
701  );
702  }
703 }
704 
705 //! A general triangle specified by two sides and the included angle.
706 /***************************************************************************//**
707  \param s1 <decimal> The length of the side 1.
708  \param a <decimal> The included angle in degrees.
709  \param s2 <decimal> The length of the side 2.
710 
711  \param x <decimal> The side to draw on the positive x-axis (\p x=1 for \p s1).
712 
713  \param vr <decimal> The default vertex rounding radius.
714  \param v1r <decimal> Vertex 1 rounding radius.
715  \param v2r <decimal> Vertex 2 rounding radius.
716  \param v3r <decimal> Vertex 3 rounding radius.
717 
718  \param centroid <boolean> Center centroid at origin.
719  \param incenter <boolean> Center incenter at origin.
720 
721  \details
722 
723  \b Example
724  \amu_eval ( function=triangle_lal ${example_dim} )
725 
726  See [Wikipedia](https://en.wikipedia.org/wiki/Solution_of_triangles)
727  for more information.
728 *******************************************************************************/
729 module triangle_lal
730 (
731  s1,
732  a,
733  s2,
734  x = 1,
735  vr,
736  v1r,
737  v2r,
738  v3r,
739  centroid = false,
740  incenter = false
741 )
742 {
743  s3 = sqrt( s1*s1 + s2*s2 - 2*s1*s2*cos(a) );
744 
745  if ( x%4 == 1 )
746  {
748  (
749  s1=s1, s2=s2, s3=s3,
750  vr=vr, v1r=v1r, v2r=v2r, v3r=v3r,
751  centroid=centroid, incenter=incenter
752  );
753  }
754  else if ( x%4 == 2 )
755  {
757  (
758  s1=s2, s2=s3, s3=s1,
759  vr=vr, v1r=v2r, v2r=v3r, v3r=v1r,
760  centroid=centroid, incenter=incenter
761  );
762  }
763  else if ( x%4 == 3 )
764  {
766  (
767  s1=s3, s2=s1, s3=s2,
768  vr=vr, v1r=v3r, v2r=v1r, v3r=v2r,
769  centroid=centroid, incenter=incenter
770  );
771  }
772 }
773 
774 //! A general triangle specified by a side and two adjacent angles.
775 /***************************************************************************//**
776  \param a1 <decimal> The adjacent angle 1 in degrees.
777  \param s <decimal> The side length adjacent to the angles.
778  \param a2 <decimal> The adjacent angle 2 in degrees.
779 
780  \param x <decimal> The side to draw on the positive x-axis (\p x=1 for \p s).
781 
782  \param vr <decimal> The default vertex rounding radius.
783  \param v1r <decimal> Vertex 1 rounding radius.
784  \param v2r <decimal> Vertex 2 rounding radius.
785  \param v3r <decimal> Vertex 3 rounding radius.
786 
787  \param centroid <boolean> Center centroid at origin.
788  \param incenter <boolean> Center incenter at origin.
789 
790  \details
791 
792  \b Example
793  \amu_eval ( function=triangle_ala ${example_dim} )
794 
795  See [Wikipedia](https://en.wikipedia.org/wiki/Solution_of_triangles)
796  for more information.
797 *******************************************************************************/
798 module triangle_ala
799 (
800  a1,
801  s,
802  a2,
803  x = 1,
804  vr,
805  v1r,
806  v2r,
807  v3r,
808  centroid = false,
809  incenter = false
810 )
811 {
812  if ( (a1 + a2) >= 180 )
813  {
814  log_warn
815  (
816  str( "can not render triangle with angles (", a1, ", ", a2, ")" )
817  );
818  }
819  else
820  {
821  s3 = s;
822  a3 = 180 - a1 - a2;
823 
824  s1 = s3 * sin( a1 ) / sin( a3 );
825  s2 = s3 * sin( a2 ) / sin( a3 );
826 
827  if ( x%4 == 1 )
828  {
830  (
831  s1=s3, s2=s1, s3=s2,
832  vr=vr, v1r=v3r, v2r=v1r, v3r=v2r,
833  centroid=centroid, incenter=incenter
834  );
835  }
836  else if ( x%4 == 2 )
837  {
839  (
840  s1=s1, s2=s2, s3=s3,
841  vr=vr, v1r=v1r, v2r=v2r, v3r=v3r,
842  centroid=centroid, incenter=incenter
843  );
844  }
845  else if ( x%4 == 3 )
846  {
848  (
849  s1=s2, s2=s3, s3=s1,
850  vr=vr, v1r=v2r, v2r=v3r, v3r=v1r,
851  centroid=centroid, incenter=incenter
852  );
853  }
854  }
855 }
856 
857 //! A general triangle specified by a side, one adjacent angle and the opposite angle.
858 /***************************************************************************//**
859  \param a1 <decimal> The opposite angle 1 in degrees.
860  \param a2 <decimal> The adjacent angle 2 in degrees.
861  \param s <decimal> The side length.
862 
863  \param x <decimal> The side to draw on the positive x-axis (\p x=1 for \p s).
864 
865  \param vr <decimal> The default vertex rounding radius.
866  \param v1r <decimal> Vertex 1 rounding radius.
867  \param v2r <decimal> Vertex 2 rounding radius.
868  \param v3r <decimal> Vertex 3 rounding radius.
869 
870  \param centroid <boolean> Center centroid at origin.
871  \param incenter <boolean> Center incenter at origin.
872 
873  \details
874 
875  \b Example
876  \amu_eval ( function=triangle_aal ${example_dim} )
877 
878  See [Wikipedia](https://en.wikipedia.org/wiki/Solution_of_triangles)
879  for more information.
880 *******************************************************************************/
881 module triangle_aal
882 (
883  a1,
884  a2,
885  s,
886  x = 1,
887  vr,
888  v1r,
889  v2r,
890  v3r,
891  centroid = false,
892  incenter = false
893 )
894 {
895  if ( (a1 + a2) >= 180 )
896  {
897  log_warn
898  (
899  str( "can not render triangle with angles (", a1, ", ", a2, ")" )
900  );
901  }
902  else
903  {
904  s1 = s;
905  a3 = 180 - a1 - a2;
906 
907  s2 = s1 * sin( a2 ) / sin( a1 );
908  s3 = s1 * sin( a3 ) / sin( a1 );
909 
910  if ( x%4 == 1 )
911  {
913  (
914  s1=s1, s2=s2, s3=s3,
915  vr=vr, v1r=v1r, v2r=v2r, v3r=v3r,
916  centroid=centroid, incenter=incenter
917  );
918  }
919  else if ( x%4 == 2 )
920  {
922  (
923  s1=s2, s2=s3, s3=s1,
924  vr=vr, v1r=v2r, v2r=v3r, v3r=v1r,
925  centroid=centroid, incenter=incenter
926  );
927  }
928  else if ( x%4 == 3 )
929  {
931  (
932  s1=s3, s2=s1, s3=s2,
933  vr=vr, v1r=v3r, v2r=v1r, v3r=v2r,
934  centroid=centroid, incenter=incenter
935  );
936  }
937  }
938 }
939 
940 //! A right-angled triangle specified by its opposite and adjacent side lengths.
941 /***************************************************************************//**
942  \param x <decimal> The length of the side along the x-axis.
943  \param y <decimal> The length of the side along the y-axis.
944 
945  \param vr <decimal> The default vertex rounding radius.
946  \param v1r <decimal> Vertex 1 rounding radius.
947  \param v2r <decimal> Vertex 2 rounding radius.
948  \param v3r <decimal> Vertex 3 rounding radius.
949 
950  \param centroid <boolean> Center centroid at origin.
951  \param incenter <boolean> Center incenter at origin.
952 
953  \details
954 
955  \b Example
956  \amu_eval ( function=triangle_ll ${example_dim} )
957 *******************************************************************************/
958 module triangle_ll
959 (
960  x,
961  y,
962  vr,
963  v1r,
964  v2r,
965  v3r,
966  centroid = false,
967  incenter = false
968 )
969 {
971  (
972  v1=origin2d, v2=[x,0], v3=[0,y],
973  vr=vr, v1r=v1r, v2r=v2r, v3r=v3r,
974  centroid=centroid, incenter=incenter
975  );
976 }
977 
978 //! A right-angled triangle specified by a side length and an angle.
979 /***************************************************************************//**
980  \param x <decimal> The length of the side along the x-axis.
981  \param y <decimal> The length of the side along the y-axis.
982  \param aa <decimal> The adjacent angle in degrees.
983  \param oa <decimal> The opposite angle in degrees.
984 
985  \param vr <decimal> The default vertex rounding radius.
986  \param v1r <decimal> Vertex 1 rounding radius.
987  \param v2r <decimal> Vertex 2 rounding radius.
988  \param v3r <decimal> Vertex 3 rounding radius.
989 
990  \param centroid <boolean> Center centroid at origin.
991  \param incenter <boolean> Center incenter at origin.
992 
993  \details
994 
995  \b Example
996  \amu_eval ( function=triangle_la ${example_dim} )
997 
998  \note When both \p x and \p y are given, both triangles are rendered.
999  \note When both \p aa and \p oa are given, \p aa is used.
1000 *******************************************************************************/
1001 module triangle_la
1003  x,
1004  y,
1005  aa,
1006  oa,
1007  vr,
1008  v1r,
1009  v2r,
1010  v3r,
1011  centroid = false,
1012  incenter = false
1013 )
1014 {
1015  a = defined_or(aa, 90 - oa);
1016 
1017  if ( is_defined(x) )
1018  {
1019  triangle_ppp
1020  (
1021  v1=origin2d, v2=[x,0], v3=[0,tan(a)*x],
1022  vr=vr, v1r=v1r, v2r=v2r, v3r=v3r,
1023  centroid=centroid, incenter=incenter
1024  );
1025  }
1026 
1027  if ( is_defined(y) )
1028  {
1029  triangle_ppp
1030  (
1031  v1=origin2d, v2=[tan(a)*y,0], v3=[0,y],
1032  vr=vr, v1r=v1r, v2r=v2r, v3r=v3r,
1033  centroid=centroid, incenter=incenter
1034  );
1035  }
1036 }
1037 
1038 //! An n-sided equiangular/equilateral regular polygon.
1039 /***************************************************************************//**
1040  \param n <decimal> The number of sides.
1041  \param r <decimal> The ngon vertex radius.
1042 
1043  \param vr <decimal> The vertex rounding radius.
1044 
1045  \details
1046 
1047  \b Example
1048  \amu_eval ( function=ngon ${example_dim} )
1049 
1050  See [Wikipedia](https://en.wikipedia.org/wiki/Regular_polygon)
1051  for more information.
1052 *******************************************************************************/
1053 module ngon
1055  n,
1056  r,
1057  vr
1058 )
1059 {
1060  if ( not_defined(vr) )
1061  {
1062  circle(r=r, $fn=n);
1063  }
1064  else
1065  {
1066  hull()
1067  {
1068  for ( c = ngon_vp( r=r, n=n, vr=vr ) )
1069  {
1070  translate( c )
1071  circle( r=vr );
1072  }
1073  }
1074  }
1075 }
1076 
1077 //! An ellipse.
1078 /***************************************************************************//**
1079  \param size <vector|decimal> A vector [rx, ry] of decimals
1080  or a single decimal for (rx=ry).
1081 
1082  \details
1083 
1084  \b Example
1085  \amu_eval ( function=ellipse ${example_dim} )
1086 *******************************************************************************/
1087 module ellipse
1089  size
1090 )
1091 {
1092  rx = edefined_or(size, 0, size);
1093  ry = edefined_or(size, 1, rx);
1094 
1095  if ( rx == ry )
1096  {
1097  circle(r=rx);
1098  }
1099  else
1100  {
1101  scale([1, ry/rx])
1102  circle(r=rx);
1103  }
1104 }
1105 
1106 //! An ellipse with a removed elliptical core.
1107 /***************************************************************************//**
1108  \param size <vector|decimal> A vector [rx, ry] of decimals
1109  or a single decimal for (rx=ry).
1110  \param core <vector|decimal> A vector [rx, ry] of decimals
1111  or a single decimal for (rx=ry).
1112 
1113  \param t <vector|decimal> A vector [x, y] of decimals
1114  or a single decimal for (x=y).
1115 
1116  \param co <vector> Core offset. A vector [x, y] of decimals.
1117  \param cr <decimal> Core z-rotation.
1118 
1119  \details
1120 
1121  Thickness \p t
1122  \li <tt>core = size - t</tt>; when \p t and \p size are given.
1123  \li <tt>size = core + t</tt>; when \p t and \p core are given.
1124 
1125  \b Example
1126  \amu_eval ( function=ellipse_c ${example_dim} )
1127 *******************************************************************************/
1128 module ellipse_c
1130  size,
1131  core,
1132  t,
1133  co,
1134  cr = 0
1135 )
1136 {
1137  od = all_defined([t, core]) ? (core + t) : size;
1138  id = all_defined([t, size]) ? (size - t) : core;
1139 
1140  if ( is_defined(id) )
1141  {
1142  difference()
1143  {
1144  ellipse(size=od);
1145 
1146  translate(is_defined(co) ? co : origin2d)
1147  rotate([0, 0, cr])
1148  ellipse(size=id);
1149  }
1150  }
1151  else
1152  {
1153  ellipse(size=od);
1154  }
1155 }
1156 
1157 //! An ellipse sector.
1158 /***************************************************************************//**
1159  \param size <vector|decimal> A vector [rx, ry] of decimals
1160  or a single decimal for (rx=ry).
1161 
1162  \param a1 <decimal> The start angle in degrees.
1163  \param a2 <decimal> The stop angle in degrees.
1164 
1165  \details
1166 
1167  \b Example
1168  \amu_eval ( function=ellipse_s ${example_dim} )
1169 *******************************************************************************/
1170 module ellipse_s
1172  size,
1173  a1 = 0,
1174  a2 = 0
1175 )
1176 {
1177  rx = edefined_or(size, 0, size);
1178  ry = edefined_or(size, 1, rx);
1179 
1180  trx = rx * sqrt(2) + 1;
1181  try = ry * sqrt(2) + 1;
1182 
1183  pa0 = (4 * a1 + 0 * a2) / 4;
1184  pa1 = (3 * a1 + 1 * a2) / 4;
1185  pa2 = (2 * a1 + 2 * a2) / 4;
1186  pa3 = (1 * a1 + 3 * a2) / 4;
1187  pa4 = (0 * a1 + 4 * a2) / 4;
1188 
1189  if (a2 > a1)
1190  {
1191  intersection()
1192  {
1193  ellipse(size);
1194 
1195  polygon
1196  ([
1197  origin2d,
1198  [trx * cos(pa0), try * sin(pa0)],
1199  [trx * cos(pa1), try * sin(pa1)],
1200  [trx * cos(pa2), try * sin(pa2)],
1201  [trx * cos(pa3), try * sin(pa3)],
1202  [trx * cos(pa4), try * sin(pa4)],
1203  origin2d
1204  ]);
1205  }
1206  }
1207  else
1208  {
1209  ellipse(size);
1210  }
1211 }
1212 
1213 //! A sector of an ellipse with a removed elliptical core.
1214 /***************************************************************************//**
1215  \param size <vector|decimal> A vector [rx, ry] of decimals
1216  or a single decimal for (rx=ry).
1217  \param core <vector|decimal> A vector [rx, ry] of decimals
1218  or a single decimal for (rx=ry).
1219 
1220  \param t <vector|decimal> A vector [x, y] of decimals
1221  or a single decimal for (x=y).
1222 
1223  \param a1 <decimal> The start angle in degrees.
1224  \param a2 <decimal> The stop angle in degrees.
1225 
1226  \param co <vector> Core offset. A vector [x, y] of decimals.
1227  \param cr <decimal> Core z-rotation.
1228 
1229  \details
1230 
1231  Thickness \p t
1232  \li <tt>core = size - t</tt>; when \p t and \p size are given.
1233  \li <tt>size = core + t</tt>; when \p t and \p core are given.
1234 
1235  \b Example
1236  \amu_eval ( function=ellipse_cs ${example_dim} )
1237 *******************************************************************************/
1238 module ellipse_cs
1240  size,
1241  core,
1242  t,
1243  a1 = 0,
1244  a2 = 0,
1245  co,
1246  cr = 0
1247 )
1248 {
1249  od = all_defined([t, core]) ? (core + t) : size;
1250  id = all_defined([t, size]) ? (size - t) : core;
1251 
1252  if ( is_defined(id) )
1253  {
1254  difference()
1255  {
1256  ellipse_s(a1=a1, a2=a2, size=od);
1257 
1258  translate(is_defined(co) ? co : origin2d)
1259  rotate([0, 0, cr])
1260  ellipse(size=id);
1261  }
1262  }
1263  else
1264  {
1265  ellipse_s(a1=a1, a2=a2, size=od);
1266  }
1267 }
1268 
1269 //! A two dimensional star.
1270 /***************************************************************************//**
1271  \param size <vector|decimal> A vector [l, w] of decimals
1272  or a single decimal for (size=l=2*w).
1273 
1274  \param n <decimal> The number of points.
1275 
1276  \param vr <vector|decimal> The vertex rounding radius. A vector
1277  [v1r, v2r, v3r] of decimals or a single decimal for (v1r=v2r=v3r).
1278 
1279  \details
1280 
1281  \b Example
1282  \amu_eval ( function=star2d ${example_dim} )
1283 *******************************************************************************/
1284 module star2d
1286  size,
1287  n = 5,
1288  vr
1289 )
1290 {
1291  l = edefined_or(size, 0, size);
1292  w = edefined_or(size, 1, l/2);
1293 
1294  st_radial_copy(n=n, angle=true, move=false)
1295  rotate([0, 0, -90])
1296  translate([-w/2, 0])
1297  triangle_vl(v=[w, l, l], vr=vr);
1298 }
1299 
1300 //! @}
1301 //! @}
1302 
1303 //----------------------------------------------------------------------------//
1304 // openscad-amu auxiliary scripts
1305 //----------------------------------------------------------------------------//
1306 
1307 /*
1308 BEGIN_SCOPE dim;
1309  BEGIN_OPENSCAD;
1310  include <shapes2d.scad>;
1311 
1312  shape = "ellipse_cs";
1313  $fn = 72;
1314 
1315  if (shape == "rectangle")
1316  rectangle( size=[25,40], vr=[0,10,10,5], vrm=4, center=true );
1317  else if (shape == "rectangle_c")
1318  rectangle_c( size=[40,25], t=[15,5], vr1=[0,0,10,10], vr2=2.5, vrm2=3, co=[0,5], center=true );
1319  else if (shape == "rhombus")
1320  rhombus( size=[40,25], vr=[2,4,2,4], center=true );
1321  else if (shape == "triangle_ppp")
1322  triangle_ppp( v1=[0,0], v2=[5,25], v3=[40,5], vr=2, centroid=true );
1323  else if (shape == "triangle_lll")
1324  triangle_lll( s1=30, s2=40, s3=50, vr=2, centroid=true );
1325  else if (shape == "triangle_vl_c")
1326  triangle_vl_c( vs=[30,50,50], vc=[20,40,40], co=[0,-4], vr1=[1,1,6], vr2=4, centroid=true );
1327  else if (shape == "triangle_lal")
1328  triangle_lal( s1=50, a=60, s2=30, vr=2, centroid=true );
1329  else if (shape == "triangle_ala")
1330  triangle_ala( a1=30, s=50, a2=60, vr=2, centroid=true );
1331  else if (shape == "triangle_aal")
1332  triangle_aal( a1=60, a2=30, s=40, vr=2, centroid=true );
1333  else if (shape == "triangle_ll")
1334  triangle_ll( x=30, y=40, vr=2, centroid=true );
1335  else if (shape == "triangle_la")
1336  triangle_la( x=40, aa=30, vr=2, centroid=true );
1337  else if (shape == "ngon")
1338  ngon( n=6, r=25, vr=6 );
1339  else if (shape == "ellipse")
1340  ellipse( size=[25, 40] );
1341  else if (shape == "ellipse_c")
1342  ellipse_c( size=[25,40], core=[16,10], co=[0,10], cr=45 );
1343  else if (shape == "ellipse_s")
1344  ellipse_s( size=[25,40], a1=90, a2=180 );
1345  else if (shape == "ellipse_cs")
1346  ellipse_cs( size=[25,40], t=[10,5], a1=90, a2=180, co=[10,0], cr=45);
1347  else if (shape == "star2d")
1348  star2d( size=[40, 15], n=5, vr=2 );
1349  END_OPENSCAD;
1350 
1351  BEGIN_MFSCRIPT;
1352  include --path "${INCLUDE_PATH}" {config_base,config_png}.mfs;
1353 
1354  views name "views" views "top";
1355  defines name "shapes" define "shape"
1356  strings "
1357  rectangle
1358  rectangle_c
1359  rhombus
1360  triangle_ppp
1361  triangle_lll
1362  triangle_vl_c
1363  triangle_lal
1364  triangle_ala
1365  triangle_aal
1366  triangle_ll
1367  triangle_la
1368  ngon
1369  ellipse
1370  ellipse_c
1371  ellipse_s
1372  ellipse_cs
1373  star2d
1374  ";
1375  variables add_opts_combine "views shapes";
1376  variables add_opts "--viewall --autocenter";
1377 
1378  include --path "${INCLUDE_PATH}" script_std.mfs;
1379  END_MFSCRIPT;
1380 END_SCOPE;
1381 
1382 BEGIN_SCOPE manifest;
1383  BEGIN_OPENSCAD;
1384  include <shapes2d.scad>;
1385 
1386  $fn = 72;
1387 
1388  st_cartesian_copy( grid=5, incr=60, center=true )
1389  {
1390  rectangle( size=[25,40], vr=[0,10,10,5], vrm=4, center=true );
1391  rectangle_c( size=[40,25], t=[15,5], vr1=[0,0,10,10], vr2=2.5, vrm2=3, co=[0,5], center=true );
1392  rhombus( size=[40,25], vr=[2,4,2,4], center=true );
1393  triangle_ppp( v1=[0,0], v2=[5,25], v3=[40,5], vr=2, centroid=true );
1394  triangle_lll( s1=30, s2=40, s3=50, vr=2, centroid=true );
1395  triangle_vl_c( vs=[30,50,50], vc=[20,40,40], co=[0,-4], vr1=[1,1,6], vr2=4, centroid=true );
1396  triangle_lal( s1=50, a=60, s2=30, vr=2, centroid=true );
1397  triangle_ala( a1=30, s=50, a2=60, vr=2, centroid=true );
1398  triangle_aal( a1=60, a2=30, s=40, vr=2, centroid=true );
1399  triangle_ll( x=30, y=40, vr=2, centroid=true );
1400  triangle_la( x=40, aa=30, vr=2, centroid=true );
1401  ngon( n=6, r=25, vr=6 );
1402  ellipse( size=[25, 40] );
1403  ellipse_c( size=[25,40], core=[16,10], co=[0,10], cr=45 );
1404  ellipse_s( size=[25,40], a1=90, a2=180 );
1405  ellipse_cs( size=[25,40], t=[10,5], a1=90, a2=180, co=[10,0], cr=45);
1406  star2d( size=[40, 15], n=5, vr=2 );
1407  }
1408  END_OPENSCAD;
1409 
1410  BEGIN_MFSCRIPT;
1411  include --path "${INCLUDE_PATH}" {config_base,config_svg}.mfs;
1412  include --path "${INCLUDE_PATH}" script_std.mfs;
1413  END_MFSCRIPT;
1414 END_SCOPE;
1415 */
1416 
1417 //----------------------------------------------------------------------------//
1418 // end of file
1419 //----------------------------------------------------------------------------//
function defined_or(v, d)
Return a defined or default value.
function angle_vv(v1t, v2t, v1i, v2i)
Compute the angle between two vectors in a Euclidean 2 or 3D-space.
module rectangle(size, vr, vrm=0, center=false)
A rectangle with edge, fillet, and/or chamfer corners.
Definition: shapes2d.scad:112
module ellipse_cs(size, core, t, a1=0, a2=0, co, cr=0)
A sector of an ellipse with a removed elliptical core.
Definition: shapes2d.scad:1239
module ngon(n, r, vr)
An n-sided equiangular/equilateral regular polygon.
Definition: shapes2d.scad:1054
function triangle_centroid_vp(v)
Compute the centroid (geometric center) of a triangle.
function is_nan(v)
Test if a numerical value is invalid.
module triangle_vl_c(vs, vc, co, cr=0, vr, vr1, vr2, centroid=false, incenter=false)
A general triangle specified by its sides with a removed triangular core.
Definition: shapes2d.scad:638
module triangle_lal(s1, a, s2, x=1, vr, v1r, v2r, v3r, centroid=false, incenter=false)
A general triangle specified by two sides and the included angle.
Definition: shapes2d.scad:730
module triangle_la(x, y, aa, oa, vr, v1r, v2r, v3r, centroid=false, incenter=false)
A right-angled triangle specified by a side length and an angle.
Definition: shapes2d.scad:1002
module rectangle_c(size, core, t, co, cr=0, vr, vr1, vr2, vrm=0, vrm1, vrm2, center=false)
A rectangle with a removed rectangular core.
Definition: shapes2d.scad:232
function unit_v(vt, vi)
Compute the normalized unit vector for a 1, 2, or 3 term vector.
module ellipse_c(size, core, t, co, cr=0)
An ellipse with a removed elliptical core.
Definition: shapes2d.scad:1129
function not_defined(v)
Test if a value is not defined.
module ellipse_s(size, a1=0, a2=0)
An ellipse sector.
Definition: shapes2d.scad:1171
module triangle_ala(a1, s, a2, x=1, vr, v1r, v2r, v3r, centroid=false, incenter=false)
A general triangle specified by a side and two adjacent angles.
Definition: shapes2d.scad:799
eps
Epsilon, small distance to deal with overlaping shapes
Definition: constants.scad:47
module triangle_aal(a1, a2, s, x=1, vr, v1r, v2r, v3r, centroid=false, incenter=false)
A general triangle specified by a side, one adjacent angle and the opposite angle.
Definition: shapes2d.scad:882
module st_radial_copy(n, r=1, angle=true, move=false)
Distribute copies of a 2D or 3D shape equally about a z-axis radius.
Definition: transform.scad:322
function triangle_centroid_ppp(v1, v2, v3)
Compute the centroid (geometric center) of a triangle.
module log_warn(m)
Output warning message to console.
Definition: console.scad:109
module triangle_vp(v, vr, centroid=false, incenter=false)
A general triangle specified by a vector of its three vertices.
Definition: shapes2d.scad:474
module triangle_vl(v, vr, centroid=false, incenter=false)
A general triangle specified by a vector of its three side lengths.
Definition: shapes2d.scad:584
function ngon_vp(n, r, vr)
Compute the vertices for an n-sided equiangular/equilateral regular polygon.
function any_undefined(v)
Test if any element of a value is undefined.
function triangle_incenter_ppp(v1, v2, v3)
Compute the coordinate for the triangle's incircle.
function edefined_or(v, i, d)
Return a defined vector element or default value.
function is_scalar(v)
Test if a value is a single non-iterable value.
function bitwise_is_equal(v, b, t=1)
Test if a base-two bit position of an integer value equals a test bit.
module triangle_ppp(v1, v2, v3, vr, v1r, v2r, v3r, centroid=false, incenter=false)
A general triangle specified by three vertices.
Definition: shapes2d.scad:398
origin2d
The origin coordinates in 2-dimensional Euclidean space.
Definition: constants.scad:105
function all_defined(v)
Test if no element of a value is undefined.
function is_defined(v)
Test if a value is defined.
function triangle_incenter_vp(v)
Compute the coordinate for the triangle's incircle.
function triangle_lll2vp(s1, s2, s3)
Compute the vertices of a plane triangle given its side lengths.
module star2d(size, n=5, vr)
A two dimensional star.
Definition: shapes2d.scad:1285
module triangle_ll(x, y, vr, v1r, v2r, v3r, centroid=false, incenter=false)
A right-angled triangle specified by its opposite and adjacent side lengths.
Definition: shapes2d.scad:959
module triangle_lll(s1, s2, s3, vr, v1r, v2r, v3r, centroid=false, incenter=false)
A general triangle specified by its three side lengths.
Definition: shapes2d.scad:524
module rhombus(size, vr, center=false)
A rhombus.
Definition: shapes2d.scad:297
module ellipse(size)
An ellipse.
Definition: shapes2d.scad:1088