omdl  v0.9.5
OpenSCAD Mechanical Design Library
polytope.scad
Go to the documentation of this file.
1 //! Polytope shapes, conversions, properties, and tests functions.
2 /***************************************************************************//**
3  \file
4  \author Roy Allen Sutton
5  \date 2017-2024
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 (Polytopes)
31  \amu_define group_brief (Polytope mathematical functions.)
32 
33  \amu_include (include/amu/pgid_path_pstem_pg.amu)
34 *******************************************************************************/
35 
36 //----------------------------------------------------------------------------//
37 // group.
38 //----------------------------------------------------------------------------//
39 
40 /***************************************************************************//**
41  \amu_include (include/amu/group_in_parent_start.amu)
42  \amu_include (include/amu/includes_required.amu)
43 *******************************************************************************/
44 
45 //----------------------------------------------------------------------------//
46 // General
47 //----------------------------------------------------------------------------//
48 
49 //! \name General
50 //! @{
51 
52 //! List the edge coordinate index pairs of a polytope.
53 /***************************************************************************//**
54  \param f <integer-list-list> A list of faces (or paths) that enclose
55  the shape where each face is a list of coordinate indexes.
56 
57  \returns <integer-list-2-list> A list of edges where each edge is
58  a list of two coordinate indexes that form the shape.
59 
60  \details
61 
62  \note Although the edge list is not sorted, each pair is sorted
63  with the smallest index first.
64 *******************************************************************************/
65 function polytope_faces2edges
66 (
67  f
68 ) =
69  let
70  (
71  el =
72  [
73  for (ip = [for (fi = f) for (ai = sequence_ns(fi, n=2, s=1, w=true)) ai])
74  [min(ip), max(ip)]
75  ]
76  )
77  unique(el);
78 
79 //! Get a line from an edge or any two vetices of a polytope.
80 /***************************************************************************//**
81  \param c <coords-3d | coords-2d> A list of 3d or 2d coordinate points.
82 
83  \param f <integer-list-list> A list of faces (or paths) that enclose
84  the shape where each face is a list of coordinate indexes.
85  \param e <integer-list-2-list> A list of edges where each edge is
86  a list of two coordinate indexes.
87 
88  \param i <integer> A line specified as an edge index.
89  \param l <integer-list-2> A line specified as a list of coordinate
90  index pairs.
91 
92  \param r <boolean> Reverse the start and end points of the line
93  specified as an edge index \p i.
94 
95  \returns <line-3d | line-2d> The line as a pair of coordinates.
96 
97  \details
98 
99  \note Parameter \p f is optional for polygons. When it is not
100  given, the listed order of the coordinates \p c establishes
101  the polygon path.
102  \note When \p e is not specified, it is computed from \p f using
103  polytope_faces2edges() iff the line is identified by \p i.
104 *******************************************************************************/
105 function polytope_line
106 (
107  c,
108  f,
109  e,
110  i,
111  l,
112  r = false
113 ) = is_defined(l) ? [c[first(l)], c[second(l)]]
114  : is_undef(i) ? undef
115  : let
116  (
117  fm = defined_or(f, [consts(len(c))]),
118  el = defined_or(e, polytope_faces2edges(fm)),
119  sl = el[i]
120  )
121  (r == false)
122  ? [c[second(sl)], c[first(sl)]]
123  : [c[first(sl)], c[second(sl)]];
124 
125 //! Determine the bounding limits of a polytope.
126 /***************************************************************************//**
127  \param c <coords-3d | coords-2d> A list of 3d or 2d cartesian
128  coordinates [[x, y (, z)], ...].
129  \param f <integer-list-list> A list of faces (or paths) that enclose
130  the shape where each face is a list of coordinate indexes.
131  \param a <decimal-list-1:3 | decimal> The box padding.
132  A list of lengths to equally pad the box dimensions.
133  \param d <range|list|integer> The dimensions to consider. A range
134  of dimensions, a list of dimensions, or a single dimension.
135  \param s <boolean> Return box size rather than coordinate limits.
136 
137  \returns <datastruct> The bounding-box limits (see: table).
138 
139  \details
140 
141  The returned datastruct will be one of the following forms:
142 
143  | | s | x | y | z | datastruct form |
144  |:---:|:-----:|:---------:|:---------:|:---------:|:---------------------:|
145  | 2d | false | [min,max] | [min,max] | - | decimal-list-2-list-2 |
146  | 2d | true | max-min | max-min | - | decimal-list-list-2 |
147  | 3d | false | [min,max] | [min,max] | [min,max] | decimal-list-2-list-3 |
148  | 3d | true | max-min | max-min | max-min | decimal-list-list-3 |
149 
150  \note When \p f is not specified, all coordinates are used to
151  determine the geometric limits, which, simplifies the
152  calculation. Parameter \p f is needed when a subset of the
153  coordinates should be considered.
154  \note When \p d is not specified, a check will be performed to
155  see if all coordinates of \p c are 3, 2, or 1 dimensional
156  and, if so, all axes for the determined dimension will be
157  used for \p d.
158  \warning This function does not track secondary shapes subtraction as
159  implemented by the polygon() function.
160 *******************************************************************************/
161 function polytope_limits
162 (
163  c,
164  f,
165  a,
166  d,
167  s = true
168 ) =
169  [
170  let
171  (
172  ax = is_undef(d)
173  ? (
174  all_len(c, 3) ? [0,1,2]
175  : all_len(c, 2) ? [0,1]
176  : all_len(c, 1) ? [0]
177  : undef
178  )
179  : is_range(d) ? [for (di=d) di]
180  : is_list(d) ? d
181  : is_integer(d) ? [d]
182  : undef,
183 
184  ad = (is_defined(a) && is_scalar(a)) ? a : 0,
185  ap = [for (j = ax) defined_e_or(a, j, ad)],
186 
187  pm = is_defined(f)
188  ? [for (j = ax) [for (m = f) for (i=[0 : len(m)-1]) c[m[i]][j]]]
189  : [for (j = ax) [for (i = c) i[j]]],
190 
191  b = [for (j = ax) [min(pm[j]), max(pm[j])] + [-ap[j]/2, +ap[j]/2]]
192  )
193  for (j = ax)
194  (s == true) ? b[j][1] - b[j][0] : [b[j][0], b[j][1]]
195  ];
196 
197 //! Generate a bounding box polytope for another polytope in 3d or 2d.
198 /***************************************************************************//**
199  \param c <coords-3d | coords-2d> A list of 3d or 2d cartesian
200  coordinates [[x, y (, z)], ...].
201  \param f <integer-list-list> A list of faces (or paths) that enclose
202  the shape where each face is a list of coordinate indexes.
203  \param a <decimal-list-1:3 | decimal> The box padding.
204  A list of lengths to equally pad the box dimensions.
205 
206  \returns <datastruct> A structure: (1) <tt>[points, faces]</tt>,
207  where \c points are <coords-3d> and \c faces are a
208  <integer-list-list>, that define the bounding box of the
209  given polyhedron. Or: (2) <tt>[points, path]</tt>, where
210  \c points are <coords-2d> and \c path is a
211  <integer-list-list>, that define the bounding box of the
212  given polygon.
213 
214  \details
215 
216  Polyhedron faces will be ordered \em clockwise when looking from
217  outside the shape inwards. Polygon path will be ordered clockwise
218  when looking from the top (positive z) downwards.
219 
220  \note When \p f is not specified, all coordinates are used to
221  determine the geometric limits, which, simplifies the
222  calculation. Parameter \p f is needed when a subset of the
223  coordinates should be considered.
224 
225  \sa polytope_limits for warning about secondary shapes.
226 *******************************************************************************/
228 (
229  c,
230  f,
231  a
232 ) = let
233  (
234  b = polytope_limits(c=c, f=f, a=a, s=false),
235  d = len([for (i=b) if (i != [undef, undef]) i])
236  )
237  (d == 3) ?
238  [ [for (x=b[0], y=b[1], z=b[2]) [x, y, z]],
239  [[0,2,3,1], [4,0,1,5], [6,4,5,7], [2,6,7,3], [0,4,6,2], [3,7,5,1]] ]
240  : [ [for (x=b[0], y=b[1]) [x, y]],
241  [[0,1,3,2]] ];
242 
243 //! Triangulate the faces of a convex polytope using fan triangulation.
244 /***************************************************************************//**
245  \param f <integer-list-list> A list of faces (or paths) that enclose
246  the shape where each face is a list of coordinate indexes.
247 
248  \returns <integer-list-3-list> A list of triangular faces that enclose
249  the polytope where each face is a list of three coordinate
250  indexes with vertex ordering is maintained.
251 
252  \details
253 
254  See [Wikipedia] for more information on [fan triangulation].
255 
256  [Wikipedia]: https://en.wikipedia.org/wiki/Polygon_triangulation
257  [fan triangulation]: https://en.wikipedia.org/wiki/Fan_triangulation
258 
259  \warning This method does not support concave polytopes.
260 *******************************************************************************/
262 (
263  f
264 ) =
265  [
266  for (fi = f)
267  for (ci = [1 : len(fi)-2]) [fi[0], fi[ci], fi[ci+1]]
268  ];
269 
270 //! @}
271 
272 //----------------------------------------------------------------------------//
273 // Adjacents
274 //----------------------------------------------------------------------------//
275 
276 //! \name Adjacents
277 //! @{
278 
279 //! List the adjacent vertices for a given polytope vertex.
280 /***************************************************************************//**
281  \param f <integer-list-list> A list of faces (or paths) that enclose
282  the shape where each face is a list of coordinate indexes.
283 
284  \param i <integer> A vertex index.
285 
286  \returns <integer-list> The list of adjacent vertex indexes for the
287  given vertex index.
288 
289  \details
290 
291  The adjacent vertices are those neighboring vertices that are
292  directly connected to the given vertex by a common edge.
293 
294  \note Parameter \p f is optional for polygons. When it is not
295  given, the listed order of the coordinates \p c establishes
296  the polygon path.
297 *******************************************************************************/
299 (
300  f,
301  i
302 ) =
303  let
304  (
305  vn =
306  [
307  for (fi = f) let (fn = len(fi))
308  for (j = [0:fn-1])
309  if (i == fi[j])
310  for (k = [-1, 1])
311  fi[index_c(j + k, fn)]
312  ]
313  )
314  unique(vn);
315 
316 //! List the adjacent face indexes for a polytope vertex.
317 /***************************************************************************//**
318  \param f <integer-list-list> A list of faces (or paths) that enclose
319  the shape where each face is a list of coordinate indexes.
320  \param i <integer> The vertex index.
321 
322  \returns <integer-list> The list of face indexes adjacent to the
323  given polytope vertex.
324 *******************************************************************************/
326 (
327  f,
328  i
329 ) = [for (fi = [0:len(f)-1]) if (exists(i, f[fi])) fi];
330 
331 //! List the adjacent face indexes for a polytope edge.
332 /***************************************************************************//**
333  \param f <integer-list-list> A list of faces (or paths) that enclose
334  the shape where each face is a list of coordinate indexes.
335  \param e <integer-list-2-list> A list of edges where each edge is
336  a list of two coordinate indexes.
337  \param i <integer> The edge index.
338 
339  \returns <integer-list> The list of face indexes adjacent to the
340  given polytope edge.
341 
342  \details
343 
344  \note When \p e is not specified, it is computed from \p f using
345  polytope_faces2edges().
346 *******************************************************************************/
348 (
349  f,
350  e,
351  i
352 ) = let (el = is_defined(e) ? e : polytope_faces2edges(f))
353  [
354  for (fi = [0:len(f)-1])
355  if (exists(first(el[i]), f[fi]) && exists(second(el[i]), f[fi]))
356  fi
357  ];
358 
359 //! @}
360 
361 //----------------------------------------------------------------------------//
362 // Normals
363 //----------------------------------------------------------------------------//
364 
365 //! \name Normals
366 //! @{
367 
368 //! Get a normal vector for a polytope vertex.
369 /***************************************************************************//**
370  \param c <coords-3d | coords-2d> A list of 3d or 2d coordinate points.
371  \param f <integer-list-list> A list of faces (or paths) that enclose
372  the shape where each face is a list of coordinate indexes.
373  \param i <integer> The vertex index.
374 
375  \returns <vector-3d> A normal vector for the polytope vertex.
376 
377  \details
378 
379  The normal is computed as the mean of the adjacent faces.
380 
381  \note Parameter \p f is optional for polygons. When it is not
382  given, the listed order of the coordinates \p c establishes
383  the polygon path.
384 *******************************************************************************/
385 function polytope_vertex_normal
386 (
387  c,
388  f,
389  i
390 ) = let
391  (
392  fm = defined_or(f, [consts(len(c))])
393  )
394  mean([for (j=polytope_vertex_adjacent_faces(fm, i)) unit_l(polytope_face_normal(c, l=fm[j]))]);
395 
396 //! Get a normal vector for a polytope edge.
397 /***************************************************************************//**
398  \param c <coords-3d | coords-2d> A list of 3d or 2d coordinate points.
399  \param f <integer-list-list> A list of faces (or paths) that enclose
400  the shape where each face is a list of coordinate indexes.
401  \param e <integer-list-2-list> A list of edges where each edge is
402  a list of two coordinate indexes.
403  \param i <integer> The edge index.
404 
405  \returns <vector-3d> A normal vector for the polytope edge.
406 
407  \details
408 
409  The normal is computed as the mean of the adjacent faces.
410 
411  \note Parameter \p f is optional for polygons. When it is not
412  given, the listed order of the coordinates \p c establishes
413  the polygon path.
414  \note When \p e is not specified, it is computed from \p f using
415  polytope_faces2edges().
416 *******************************************************************************/
417 function polytope_edge_normal
418 (
419  c,
420  f,
421  e,
422  i
423 ) = let
424  (
425  fm = defined_or(f, [consts(len(c))]),
426  el = is_defined(e) ? e : polytope_faces2edges(fm)
427  )
428  mean([for (j=polytope_edge_adjacent_faces(fm, el, i)) unit_l(polytope_face_normal(c, l=fm[j]))]);
429 
430 //! Get the normal vector of a polytope face.
431 /***************************************************************************//**
432  \param c <coords-3d | coords-2d> A list of 3d or 2d coordinate points.
433  \param f <integer-list-list> A list of faces (or paths) that enclose
434  the shape where each face is a list of coordinate indexes.
435 
436  \param i <integer> The face specified as an face index.
437  \param l <integer-list> The face-plane specified as a list of three
438  or more coordinate indexes that are a part of the face.
439 
440  \param cw <boolean> Face vertex ordering.
441 
442  \returns <vector-3d> The normal vector of a polytope face.
443 
444  \details
445 
446  The face can be identified using either parameter \p i or \p l.
447  When using \p l, the parameter \p f is not required.
448 
449  \note Parameter \p f is optional for polygons. When it is not
450  given, the listed order of the coordinates \p c establishes
451  the polygon path.
452 *******************************************************************************/
453 function polytope_face_normal
454 (
455  c,
456  f,
457  i,
458  l,
459  cw = true
460 ) = let
461  (
462  ci = is_defined(l) ? l : defined_or(f, [consts(len(c))])[i],
463  pc = [for (i = [0:2]) let (p = c[ci[i]]) (len(p) == 3) ? p : [p[0], p[1], 0]]
464  )
465  cross(pc[0]-pc[1], pc[2]-pc[1]) * ((cw == true) ? 1 : -1);
466 
467 //! @}
468 
469 //----------------------------------------------------------------------------//
470 // Faces
471 //----------------------------------------------------------------------------//
472 
473 //! \name Faces
474 //! @{
475 
476 //! Get the mean coordinate of all vertices of a polytope face.
477 /***************************************************************************//**
478  \param c <coords-3d | coords-2d> A list of 3d or 2d coordinate points.
479  \param f <integer-list-list> A list of faces (or paths) that enclose
480  the shape where each face is a list of coordinate indexes.
481 
482  \param i <integer> The face specified as an face index.
483  \param l <integer-list> The face specified as a list of all the
484  coordinate indexes that define it.
485 
486  \returns <coords-3d> The mean coordinate of a polytope face.
487 
488  \details
489 
490  The face can be identified using either parameter \p i or \p l.
491  When using \p l, the parameter \p f is not required.
492 
493  \note Parameter \p f is optional for polygons. When it is not
494  given, the listed order of the coordinates \p c establishes
495  the polygon path.
496 *******************************************************************************/
497 function polytope_face_mean
498 (
499  c,
500  f,
501  i,
502  l
503 ) = let
504  (
505  ci = is_defined(l) ? l : defined_or(f, [consts(len(c))])[i],
506  pc = [for (i = ci) c[i]]
507  )
508  mean(pc);
509 
510 //! Get the mean coordinate and normal vector of a polytope face.
511 /***************************************************************************//**
512  \param c <coords-3d | coords-2d> A list of 3d or 2d coordinate points.
513  \param f <integer-list-list> A list of faces (or paths) that enclose
514  the shape where each face is a list of coordinate indexes.
515 
516  \param i <integer> The face specified as an face index.
517  \param l <integer-list> The face specified as a list of all the
518  coordinate indexes that define it.
519 
520  \param cw <boolean> Face vertex ordering.
521 
522  \returns <plane> <tt>[mp, nv]</tt>, where \c mp is \c coords-3d, the
523  mean coordinate, and \c nv is \c vector-3d, the normal
524  vector, of the polytope face-plane.
525 
526  \details
527 
528  The face can be identified using either parameter \p i or \p l.
529  When using \p l, the parameter \p f is not required.
530 
531  \note Parameter \p f is optional for polygons. When it is not
532  given, the listed order of the coordinates \p c establishes
533  the polygon path.
534 *******************************************************************************/
536 (
537  c,
538  f,
539  i,
540  l,
541  cw = true
542 ) = [polytope_face_mean(c, f, i, l), polytope_face_normal(c, f, i, l, cw)];
543 
544 //! Get a plane for a polytope face.
545 /***************************************************************************//**
546  \copydetails polytope_face_mean_normal()
547 *******************************************************************************/
548 function polytope_face_plane
549 (
550  c,
551  f,
552  i,
553  l,
554  cw=true
555 ) = polytope_face_mean_normal(c, f, i, l, cw);
556 
557 //! List the vertex counts for all polytope faces.
558 /***************************************************************************//**
559  \param f <integer-list-list> A list of faces (or paths) that enclose
560  the shape where each face is a list of coordinate indexes.
561 
562  \returns <integer-list> A list with a vertex count of every face.
563 *******************************************************************************/
565 (
566  f
567 ) = [for (fi=f) len(fi)];
568 
569 //! List the angles between all adjacent faces of a polyhedron.
570 /***************************************************************************//**
571  \param c <coords-3d> A list of 3d cartesian coordinates
572  [[x, y, z], ...].
573  \param f <integer-list-list> A list of faces that enclose
574  the shape where each face is a list of coordinate indexes.
575 
576  \returns <decimal-list> A list of the polyhedron adjacent face angles.
577 
578  \details
579 
580  See [Wikipedia] for more information on dihedral angles.
581 
582  [Wikipedia]: https://en.wikipedia.org/wiki/Dihedral_angle
583 *******************************************************************************/
584 function polytope_face_angles
585 (
586  c,
587  f
588 ) =
589  [
590  for (i=[0 : len(f)-1])
591  let
592  (
593  n1 = cross_ll([c[f[i][0]], c[f[i][1]]], [c[f[i][0]], c[f[i][2]]]),
594  af = [for (v=f[i]) for (j=[0 : len(f)-1]) if (j != i && exists(v, f[j])) j]
595  )
596  for (u=unique(af))
597  let
598  (
599  n2 = cross_ll([c[f[u][0]], c[f[u][1]]], [c[f[u][0]], c[f[u][2]]])
600  )
601  angle_ll(n1, n2)
602  ];
603 
604 //! @}
605 
606 //----------------------------------------------------------------------------//
607 // Edges
608 //----------------------------------------------------------------------------//
609 
610 //! \name Edges
611 //! @{
612 
613 //! List the edge lengths of a polytope.
614 /***************************************************************************//**
615  \param c <coords-3d | coords-2d> A list of 3d or 2d cartesian
616  coordinates [[x, y (, z)], ...].
617  \param e <integer-list-2-list> A list of edges where each edge is
618  a list of two coordinate indexes.
619 
620  \returns <decimal-list> A list of the polytope edge lengths.
621 *******************************************************************************/
622 function polytope_edge_lengths
623 (
624  c,
625  e
626 ) = [for (ei=e) distance_pp(c[ei[0]], c[ei[1]])];
627 
628 //! List the adjacent edge angles for each polytope vertex.
629 /***************************************************************************//**
630  \param c <coords-3d | coords-2d> A list of 3d or 2d cartesian
631  coordinates [[x, y (, z)], ...].
632  \param f <integer-list-list> A list of faces (or paths) that enclose
633  the shape where each face is a list of coordinate indexes.
634 
635  \returns <decimal-list> A list of the polytope adjacent edge angles.
636 *******************************************************************************/
637 function polytope_edge_angles
638 (
639  c,
640  f
641 ) =
642  [
643  for (k=[for (j=f) for (i=sequence_ns(j, n=3, s=1, w=true)) i])
644  angle_ll([c[k[0]], c[k[1]]], [c[k[1]], c[k[2]]])
645  ];
646 
647 //! @}
648 
649 //----------------------------------------------------------------------------//
650 // Tests
651 //----------------------------------------------------------------------------//
652 
653 //! \name Tests
654 //! @{
655 
656 //! Test if the faces of a polytope are all regular.
657 /***************************************************************************//**
658  \param c <coords-3d | coords-2d> A list of 3d or 2d cartesian
659  coordinates [[x, y (, z)], ...].
660  \param f <integer-list-list> A list of faces (or paths) that enclose
661  the shape where each face is a list of coordinate indexes.
662  \param e <integer-list-2-list> A list of edges where each edge is
663  a list of two coordinate indexes.
664  \param d <integer> The number of significant figures used when
665  comparing lengths and angles.
666 
667  \returns <boolean> \b true when there is both a single edge length
668  and a single edge angle and \b false otherwise.
669 
670  \details
671 
672  \note When \p e is not specified, it is computed from \p f using
673  polytope_faces2edges().
674 *******************************************************************************/
676 (
677  c,
678  f,
679  e,
680  d = 6
681 ) =
682  let
683  (
684  ce = is_defined(e) ? e : polytope_faces2edges(f),
685 
686  ul = unique(round_s(polytope_edge_lengths(c, ce), d)),
687  ua = unique(round_s(polytope_edge_angles(c, f), d))
688  )
689  ((len(ul) == 1) && (len(ua) == 1));
690 
691 //! @}
692 
693 //! @}
694 //! @}
695 
696 //----------------------------------------------------------------------------//
697 // end of file
698 //----------------------------------------------------------------------------//
function angle_ll(l1, l2, s=true)
Compute the angle between two lines or vectors in a 3d or 2d-space.
function cross_ll(l1, l2)
Compute the cross product of two lines or vectors in a 3d or 2d-space.
function unit_l(l)
Compute the normalized unit vector of a line or vector.
function distance_pp(p1, p2)
Compute the distance between two points.
function unique(v)
Return a list of the unique elements of an iterable value.
function defined_e_or(v, i, d)
Return an element of an iterable when it exists or a default value otherwise.
function exists(mv, v, s=true, i)
Check for the existence of a match value in an iterable value.
function second(v)
Return the second element of an iterable value.
function first(v)
Return the first element of an iterable value.
function sequence_ns(v, n=1, s=1, w=false)
Return a list of all n-element sequential-subsets of an iterable value.
function all_len(v, l, c=0)
Test if all elements of an iterable value are iterable with a fixed length.
function mean(v)
Compute the mean/average of a list of numbers.
function consts(l, v, u=false)
Create a list of constant or incrementing elements.
function round_s(v, d=6)
Round a list of numbers to a fixed number of significant figures.
function index_c(i, l, f=0)
Return a circular index position.
function defined_or(v, d)
Return given value, if defined, or a secondary value, if primary is not defined.
function is_scalar(v)
Test if a value is a single non-iterable value.
function is_defined(v)
Test if a value is defined.
function is_integer(v)
Test if a value is an integer.
function is_range(v)
Test if a value is a range definition.
function polytope_edge_angles(c, f)
List the adjacent edge angles for each polytope vertex.
function polytope_edge_adjacent_faces(f, e, i)
List the adjacent face indexes for a polytope edge.
function polytope_face_mean_normal(c, f, i, l, cw=true)
Get the mean coordinate and normal vector of a polytope face.
function polytope_edge_normal(c, f, e, i)
Get a normal vector for a polytope edge.
function polytope_face_angles(c, f)
List the angles between all adjacent faces of a polyhedron.
function polytope_faces2edges(f)
List the edge coordinate index pairs of a polytope.
function polytope_vertex_adjacent_vertices(f, i)
List the adjacent vertices for a given polytope vertex.
function polytope_vertex_adjacent_faces(f, i)
List the adjacent face indexes for a polytope vertex.
function polytope_face_normal(c, f, i, l, cw=true)
Get the normal vector of a polytope face.
function polytope_face_vertex_counts(f)
List the vertex counts for all polytope faces.
function polytope_line(c, f, e, i, l, r=false)
Get a line from an edge or any two vetices of a polytope.
function polytope_face_mean(c, f, i, l)
Get the mean coordinate of all vertices of a polytope face.
function polytope_faces_are_regular(c, f, e, d=6)
Test if the faces of a polytope are all regular.
function polytope_bounding_box_pf(c, f, a)
Generate a bounding box polytope for another polytope in 3d or 2d.
function polytope_limits(c, f, a, d, s=true)
Determine the bounding limits of a polytope.
function polytope_face_plane(c, f, i, l, cw=true)
Get a plane for a polytope face.
function polytope_vertex_normal(c, f, i)
Get a normal vector for a polytope vertex.
function polytope_edge_lengths(c, e)
List the edge lengths of a polytope.
function polytope_ft_triangulate(f)
Triangulate the faces of a convex polytope using fan triangulation.