omdl  v1.0
OpenSCAD Mechanical Design Library
dimension.scad
Go to the documentation of this file.
1 //! Drafting: dimensioning operations.
2 /***************************************************************************//**
3  \file
4  \author Roy Allen Sutton
5  \date 2019-2023,2026
6 
7  \copyright
8 
9  This file is part of [omdl] (https://github.com/royasutton/omdl),
10  an OpenSCAD mechanical design library.
11 
12  The \em omdl is free software; you can redistribute it and/or modify
13  it under the terms of the [GNU Lesser General Public License]
14  (http://www.gnu.org/licenses/lgpl.html) as published by the Free
15  Software Foundation; either version 2.1 of the License, or (at
16  your option) any later version.
17 
18  The \em omdl is distributed in the hope that it will be useful,
19  but WITHOUT ANY WARRANTY; without even the implied warranty of
20  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21  Lesser General Public License for more details.
22 
23  You should have received a copy of the GNU Lesser General Public
24  License along with the \em omdl; if not, write to the Free Software
25  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26  02110-1301, USA; or see <http://www.gnu.org/licenses/>.
27 
28  \details
29 
30  \amu_include (include/amu/doxyg_init_pd_gds_ip.amu)
31 *******************************************************************************/
32 
33 // sub-group begin
34 /***************************************************************************//**
35  \amu_include (include/amu/doxyg_add_to_parent_open.amu)
36 *******************************************************************************/
37 
38 // sub-group reference definitions
39 /***************************************************************************//**
40  \amu_include (include/amu/scope_diagram_2d_object.amu)
41 
42  \amu_define group_references
43  (
44  [arrow]: \ref draft_arrow()
45  [facets]: \ref get_fn()
46  [round_d]: \ref round_d()
47  [round_s]: \ref round_s()
48  [style]: \ref draft_line()
49 
50  [conventions]: \ref tools_2d_drafting_conventions
51  )
52 *******************************************************************************/
53 
54 // sub-group documentation and conventions
55 /***************************************************************************//**
56  /+
57  \addtogroup \amu_eval(${parent})
58  \details
59  +/
60 *******************************************************************************/
61 
62 //----------------------------------------------------------------------------//
63 // members
64 //----------------------------------------------------------------------------//
65 
66 //----------------------------------------------------------------------------//
67 // dimension
68 //----------------------------------------------------------------------------//
69 
70 //! \name Dimensioning
71 //! @{
72 
73 //! Construct a dimension leader line at a point.
74 /***************************************************************************//**
75  \param p <point-2d> The leader line point.
76 
77  \param v1 <line-2d | decimal> The leader line 1 angle.
78  A 2d line, vector, or decimal angle.
79  \param l1 <decimal> The leader line 1 length.
80  \param v2 <line-2d | decimal> The leader line 2 angle.
81  A 2d line, vector, or decimal angle.
82  \param l2 <decimal> The leader line 2 length.
83 
84  \param h <string> An optional text heading.
85  \param t <string | string-list> A single or multi-line text string.
86  \param ts <decimal-list-3> The text size specification
87  <width, line-height, heading-height>. Sets the note box cell
88  size in units of \p cmh / \p cmv. Passed directly to
89  \ref draft_note() as its \p size parameter.
90  \param tp <integer-list-2> The text alignment point.
91  A list [tpx, tpy] of decimals. Requires \p tr.
92  \param tr <decimal> The text rotation angle.
93  \param ta <string> The text horizontal alignment. One of:
94  < \b "left" | \b "center" | \b "right" >.
95 
96  \param line <value-list-2> The note box border line configuration;
97  <width, [style]>. Consistent with the \p line parameter of
98  \ref draft_note(). When not specified, the defaults
99  \c dim-leader-box-weight and \c dim-leader-box-style from
100  \ref draft_config_map are used.
101 
102  \param w <decimal> The line weight.
103  \param s <integer | integer-list> The line [style].
104  \param a <integer | integer-list-5> The arrowhead style. A single
105  integer selects the style; a list of up to 5 fields
106  customizes fill, side, length, and angle — see the field
107  table in [arrow].
108 
109  \param off <decimal> The leader point offset.
110 
111  \param cmh <decimal> The horizontal width minimum unit cell size.
112  \param cmv <decimal> The vertical height minimum unit cell size.
113 
114  \param window <boolean> Return text window rectangle.
115  \param layers <string-list> The list of drafting layer names to
116  render this object on. Defaults to the "dim"; rendered
117  with dimension annotations. See \ref draft_layers_show and
118  the layer [conventions].
119 
120  \details
121 
122  \amu_eval ( html_image_w=256 latex_image_w="1.50in" object=draft_dim_leader ${object_diagram_2d} )
123 
124  \amu_eval(${group_references})
125 *******************************************************************************/
126 module draft_dim_leader
127 (
128  p = origin2d,
129 
130  v1 = 30,
131  l1 = _draft_get_config("dim-leader-length"),
132  v2,
133  l2,
134 
135  h,
136  t,
137  ts,
138  tp,
139  tr,
140  ta = "center",
141 
142  line,
143 
144  w = _draft_get_config("dim-leader-weight"),
145  s = _draft_get_config("dim-leader-style"),
146  a = _draft_get_config("dim-leader-arrow"),
147 
148  off = _draft_get_config("dim-offset"),
149 
150  cmh = _draft_get_config("dim-cmh"),
151  cmv = _draft_get_config("dim-cmv"),
152 
153  window = false,
154  layers = _draft_get_config("layers-dim")
155 )
156 {
157  if (_draft_layers_any_active(layers))
158  _draft_make_3d_if_configured()
159  {
160  // resolve border line config: caller-supplied 'line' overrides individual defaults
161  bw = _draft_get_config("dim-leader-box-weight");
162  bs = _draft_get_config("dim-leader-box-style");
163  lnd = is_undef(line) ? [bw, bs] : line;
164  // offset
165  plo = is_undef(off) ? p
166  : is_number(v1) ? line_tp(line2d_new(m=off, a=v1, p1=p))
167  : line_tp(line2d_new(m=off, v=v1, p1=p));
168 
169  // leader 1
170  ll1 = is_number(v1) ? line2d_new(m=l1, a=v1, p1=plo)
171  : line2d_new(m=l1, v=v1, p1=plo);
172 
173  draft_line(l=ll1, w=w, s=s, a1=a);
174 
175 
176  // leader 2
177  dv2 = defined_or(v2, ll1);
178  dl2 = defined_or(l2, l1);
179 
180  ll2 = is_number(v2) ? line2d_new(m=dl2, a=dv2, p1=line_tp(ll1))
181  : line2d_new(m=dl2, v=dv2, p1=line_tp(ll1));
182 
183  draft_line(l=ll2, w=w, s=s);
184 
185  // text rotation
186  tra = is_undef(tr) ? angle_ll(x_axis2d_uv, ll2, false)
187  : is_number(tr) ? tr
188  : angle_ll(x_axis2d_uv, tr, false);
189 
190  // text alignment point
191  dtp = is_undef(tr) ? [-1, 0]
192  : is_defined(tp) ? tp
193  : let( al2 = (angle_ll(x_axis2d_uv, ll2, false)+360-tra)%360 )
194  (al2> 45 && al2< 135) ? [ 0, 1]
195  : (al2>=135 && al2<=225) ? [ 1, 0]
196  : (al2> 225 && al2< 315) ? [ 0,-1]
197  : [-1, 0];
198 
199  translate( line_tp(ll2) )
200  rotate( [0, 0, tra] )
201  draft_note
202  (
203  head=h,
204  note=t,
205  size=ts,
206  line=lnd,
207  halign=ta,
208  cmh=cmh,
209  cmv=cmv,
210  zp=dtp,
211  window=window,
212  layers=layers,
213  $draft_make_3d=false
214  );
215  }
216 }
217 
218 //! Construct a dimension line between two points.
219 /***************************************************************************//**
220  \param p1 <point-2d> The dimension point 1.
221  \param p2 <point-2d> The dimension point 2.
222 
223  \param v1 <line-2d | decimal> The point 1 extension line vector.
224  A 2d line, vector, or decimal angle.
225  \param v2 <line-2d | decimal> The point 2 extension line vector.
226  A 2d line, vector, or decimal angle.
227 
228  \param t <string | string-list> A single or multi-line text string
229  that overrides the measured distance.
230  \param u <string> The units for the measured distance.
231  One of the predefined in \ref units_length.
232 
233  \param d <decimal | decimal-list-2> The minimum distance between the
234  reference point and the start of the extension line.
235  A list [d1, d2] of decimals or a single decimal for (d1=d2).
236  When d1 ≠ d2 the extension lines begin at independent distances
237  from their respective reference points; both arrowheads are
238  then projected onto the dimension line of the farther endpoint
239  so that the dimension line remains straight.
240  \param e <decimal | decimal-list-2> The length of the extension line.
241  A list [e1, e2] of decimals or a single decimal for (e1=e2).
242  \param es <integer | integer-list> The extension line [style].
243 
244  \param w <decimal> The line weight.
245  \param s <integer | integer-list> The line [style].
246 
247  \param a <integer | integer-list-5> The arrowhead style applied to
248  both ends. A single integer selects the style; a list of up
249  to 5 fields customises fill, side, length, and angle; see
250  the field table in [arrow].
251  \param a1 <integer | integer-list-5> The arrowhead 1 override;
252  when set, takes precedence over \p a for endpoint 1. See
253  the field table in [arrow].
254  \param a2 <integer | integer-list-5> The arrowhead 2 override;
255  when set, takes precedence over \p a for endpoint 2. See
256  the field table in [arrow].
257 
258  \param off <decimal> The dimension line offset.
259 
260  \param ts <decimal-list-3> The text size specification
261  <width, line-height, heading-height>. Sets the note box cell
262  size in units of \p cmh / \p cmv. Passed directly to
263  \ref draft_note() as its \p size parameter.
264  \param tp <decimal-list-2..4> The text placement point.
265  A list [tpx, tpy] of decimals that scales the note box
266  position along each axis (−1=left/bottom, +1=right/top).
267  An optional 4th element \c tp[3] adds a rotation offset in
268  degrees applied on top of the computed text angle.
269  \param rm <integer> The measurement rounding mode.
270  One of: 0=none, 1=[round_d], and 2=[round_s].
271 
272  \param cmh <decimal> The horizontal width minimum unit cell size.
273  \param cmv <decimal> The vertical height minimum unit cell size.
274 
275  \param layers <string-list> The list of drafting layer names to
276  render this object on. Defaults to the "dim"; rendered with
277  dimension annotations. See \ref draft_layers_show and the
278  layer [conventions].
279 
280  \details
281 
282  Only one of \p v1 or \p v2 should normally be used at a time. When
283  neither is specified, the extension line vector angle will be at a
284  right angle to the line formed by the dimension points \p p1 and \p
285  p2.
286 
287  \amu_eval ( html_image_w=512 latex_image_w="3.00in" object=draft_dim_line ${object_diagram_2d} )
288 
289  \amu_eval(${group_references})
290 *******************************************************************************/
291 module draft_dim_line
292 (
293  p1 = origin2d,
294  p2 = origin2d,
295 
296  v1,
297  v2,
298 
299  t,
300  u,
301 
302  d = _draft_get_config("dim-line-distance"),
303  e = _draft_get_config("dim-line-extension-length"),
304  es = _draft_get_config("dim-line-extension-style"),
305 
306  w = _draft_get_config("dim-line-weight"),
307  s = _draft_get_config("dim-line-style"),
308  a = _draft_get_config("dim-line-arrow"),
309 
310  a1,
311  a2,
312 
313  off = _draft_get_config("dim-offset"),
314 
315  ts = _draft_get_config("dim-text-size"),
316  tp = _draft_get_config("dim-text-place"),
317  rm = _draft_get_config("dim-round-mode"),
318 
319  cmh = _draft_get_config("dim-cmh"),
320  cmv = _draft_get_config("dim-cmv"),
321 
322  layers = _draft_get_config("layers-dim")
323 )
324 {
325  assert
326  (
327  distance_pp(p1, p2) > 0,
328  str("draft_dim_line: p1 and p2 must be distinct points; got p1=", p1, " p2=", p2)
329  );
330 
331  if (_draft_layers_any_active(layers))
332  _draft_make_3d_if_configured()
333  {
334  // identify measurement reference points
335  // only one of 'v1', 'v2' should normally be used at a time
336  // create vector if numerical angle has been specified.
337  mr1 = is_undef(v1) ? p1
338  : let( va1 = is_number(v1) ? line2d_new(a=v1, p1=p1) : v1 )
339  point_closest_pl(p2, va1);
340  mr2 = is_undef(v2) ? p2
341  : let( va2 = is_number(v2) ? line2d_new(a=v2, p1=p2) : v2 )
342  point_closest_pl(p1, va2);
343 
344  // minimum distance from reference points to dimension line
345  dm1 = defined_e_or(d, 0, d);
346  dm2 = defined_e_or(d, 1, dm1);
347 
348  // extension line lengths (back towards reference points)
349  de1 = defined_e_or(e, 0, e);
350  de2 = defined_e_or(e, 1, de1);
351 
352  // extension lines angle
353  // construct perpendicular to line form by reference points
354  ape = angle_ll(x_axis2d_uv, [mr1, mr2]) + 90;
355 
356  // extension line end points: each offset by its own independent distance
357  pe1 = line_tp(line2d_new(m=dm1, a=ape, p1=mr1));
358  pe2 = line_tp(line2d_new(m=dm2, a=ape, p1=mr2));
359 
360  // project pe1/pe2 onto a common dimension line through the farther end-point
361  // so both arrowheads lie on the same line, preserving visual alignment
362  dmt = max(dm1, dm2);
363  pa1 = line_tp(line2d_new(m=dmt-dm1, a=ape, p1=pe1));
364  pa2 = line_tp(line2d_new(m=dmt-dm2, a=ape, p1=pe2));
365 
366  // dimension line offset at extension line end-points
367  pd1 = line_tp(line2d_new(m=-off, a=ape, p1=pa1));
368  pd2 = line_tp(line2d_new(m=-off, a=ape, p1=pa2));
369 
370  //
371  // draft
372  //
373 
374  // extension lines: drawn from reference point outward to dimension line,
375  // each starting at its independently-offset end-point pe1/pe2
376  draft_line(l=line2d_new(m=-de1, a=ape, p1=pe1), w=w/2, s=es);
377  draft_line(l=line2d_new(m=-de2, a=ape, p1=pe2), w=w/2, s=es);
378 
379  // dimension text
380  dt = is_defined(t) ? t
381  : let
382  (
383  // measure distance between reference points
384  md = distance_pp(mr1, mr2),
385 
386  // use specified units 'u'
387  du = is_undef(u) ? md
388  : length(md, from=length_unit_base, to=u),
389 
390  // rounding: [mode:0, digits]
391  rs = defined_e_or(rm, 0, 0),
392 
393  rd = rs == 1 ? round_d(du, defined_e_or(rm, 1, 2))
394  : rs == 2 ? round_s(du, defined_e_or(rm, 1, 3))
395  : du
396  )
397  // add units id when 'u' is specified
398  is_undef(u) ? str(rd) : str(rd, " ", u);
399 
400  // individual or common arrowheads
401  da1 = defined_or(a1, a);
402  da2 = defined_or(a2, a);
403 
404  // when text placed over line
405  if ( second(tp) == 0 && !is_empty(dt) )
406  difference()
407  {
408  // remove window from dimension line for text
409  draft_line(l=[pd1, pd2], w=w, s=s, a1=da1, a2=da2);
410 
411  translate( (pd1+pd2)/2 )
412  rotate( [0, 0, ape-90] )
413  draft_note
414  (
415  note=dt,
416  size=ts,
417  line=[0,0],
418  halign="center",
419  cmh=cmh,
420  cmv=cmv,
421  zp=tp,
422  window=true,
423  layers=layers,
424  $draft_make_3d=false
425  );
426  }
427  else
428  {
429  draft_line(l=[pd1, pd2], w=w, s=s, a1=da1, a2=da2);
430  }
431 
432  if ( !is_empty(dt) )
433  translate( (pd1+pd2)/2 )
434  rotate( [0, 0, ape-90] )
435  draft_note
436  (
437  note=dt,
438  size=ts,
439  line=[0,0],
440  halign="center",
441  cmh=cmh,
442  cmv=cmv,
443  zp=tp,
444  window=false,
445  layers=layers,
446  $draft_make_3d=false
447  );
448  }
449 }
450 
451 //! Construct a radial dimension line.
452 /***************************************************************************//**
453  \param o <point-2d> The radius center point.
454 
455  \param p <point-2d> A point on the radius.
456  When \p p is specified, \p v is ignored — \p p takes
457  precedence. Use either \p p \b or \p v, not both.
458  \param r <decimal> The radius length.
459  \param v <line-2d | decimal> The dimension line angle for radius \p r.
460  A 2d line, vector, or decimal angle. Ignored when \p p is
461  also specified.
462 
463  \param t <string | string-list> A single or multi-line text string
464  that overrides the measured length.
465  \param u <string> The units for the measured length.
466  One of the predefined in \ref units_length.
467 
468  \param d <boolean> Construct a diameter dimension line.
469 
470  \param w <decimal> The line weight.
471  \param s <integer | integer-list> The line [style].
472 
473  \param a <integer | integer-list-5> The arrowhead style applied to
474  both ends. A single integer selects the style; a list of up
475  to 5 fields customizes fill, side, length, and angle; see
476  the field table in [arrow].
477  \param a1 <integer | integer-list-5> The arrowhead 1 override;
478  when set, takes precedence over \p a for endpoint 1. See
479  the field table in [arrow].
480  \param a2 <integer | integer-list-5> The arrowhead 2 override;
481  when set, takes precedence over \p a for endpoint 2. See
482  the field table in [arrow].
483 
484  \param off <decimal | decimal-list-2> The dimension line offset. A
485  list [o1, o2] of decimals or a single decimal for (o1=o2).
486 
487  \param ts <decimal-list-3> The text size specification
488  <width, line-height, heading-height>. Sets the note box cell
489  size in units of \p cmh / \p cmv. Passed directly to
490  \ref draft_note() as its \p size parameter.
491  \param tp <decimal-list-2..4> The text placement point.
492  A list [tpx, tpy] of decimals that scales the note box
493  position along each axis (−1=left/bottom, +1=right/top).
494  An optional 4th element \c tp[3] adds a rotation offset in
495  degrees applied on top of the computed text angle.
496  \param rm <integer> The measurement rounding mode.
497  One of: 0=none, 1=[round_d], and 2=[round_s].
498 
499  \param cmh <decimal> The horizontal width minimum unit cell size.
500  \param cmv <decimal> The vertical height minimum unit cell size.
501 
502  \param layers <string-list> The list of drafting layer names to
503  render this object on. Defaults to the "dim"; rendered with
504  dimension annotations. See \ref draft_layers_show and the
505  layer [conventions].
506 
507  \details
508 
509  \amu_eval ( html_image_w=256 latex_image_w="1.50in" object=draft_dim_radius ${object_diagram_2d} )
510 
511  \amu_eval(${group_references})
512 *******************************************************************************/
513 module draft_dim_radius
514 (
515  o = origin2d,
516 
517  p,
518  r = 1,
519  v,
520 
521  t,
522  u,
523 
524  d = false,
525 
526  w = _draft_get_config("dim-radius-weight"),
527  s = _draft_get_config("dim-radius-style"),
528  a = _draft_get_config("dim-radius-arrow"),
529 
530  a1,
531  a2,
532 
533  off = _draft_get_config("dim-offset"),
534 
535  ts = _draft_get_config("dim-text-size"),
536  tp = _draft_get_config("dim-text-place"),
537  rm = _draft_get_config("dim-round-mode"),
538 
539  cmh = _draft_get_config("dim-cmh"),
540  cmv = _draft_get_config("dim-cmv"),
541 
542  layers = _draft_get_config("layers-dim")
543 )
544 {
545  assert
546  (
547  !(is_defined(p) && is_defined(v)),
548  "draft_dim_radius: supply either p or v, not both; p takes precedence and v is ignored"
549  );
550 
551  if (_draft_layers_any_active(layers))
552  _draft_make_3d_if_configured()
553  {
554  // identify radius reference points
555  // create vector if numerical angle has been specified.
556  // p takes precedence over v when both are supplied (guarded above).
557  rr1 = o;
558  rr2 = is_defined(p) ? p
559  : is_undef(v) ? line_tp(line2d_new(m=r, p1=o))
560  : is_number(v) ? line_tp(line2d_new(m=r, a=v, p1=o))
561  : line_tp(line2d_new(m=r, v=v, p1=o));
562 
563  // identify measurement reference points
564  mr1 = d ? line_tp(line2d_new(m=distance_pp(rr1, rr2), v=[rr2, rr1], p1=rr1))
565  : rr1;
566  mr2 = rr2;
567 
568  // minimum distance from reference points to dimension line
569  do1 = defined_e_or(off, 0, off);
570  do2 = defined_e_or(off, 1, d ? do1 : 0);
571 
572  // dimension lines angle
573  ape = angle_ll(x_axis2d_uv, [mr1, mr2]);
574 
575  // dimension line offset at end-points
576  pd1 = (do1 == 0) ? mr1
577  : line_tp( line2d_new(m=distance_pp(mr1, mr2)-do1, v=[mr2, mr1], p1=mr2) );
578  pd2 = (do2 == 0) ? mr2
579  : line_tp( line2d_new(m=distance_pp(mr1, mr2)-do2, v=[mr1, mr2], p1=mr1) );
580 
581  //
582  // draft
583  //
584 
585  // dimension text
586  dt = is_defined(t) ? t
587  : let
588  (
589  // measure distance between reference points
590  md = distance_pp(mr1, mr2),
591 
592  // use specified units 'u'
593  du = is_undef(u) ? md
594  : length(md, from=length_unit_base, to=u),
595 
596  // rounding: [mode:0, digits]
597  rs = defined_e_or(rm, 0, 0),
598 
599  rd = rs == 1 ? round_d(du, defined_e_or(rm, 1, 2))
600  : rs == 2 ? round_s(du, defined_e_or(rm, 1, 3))
601  : du,
602 
603  rt = d ? "D" : "R"
604  )
605  // add units id when 'u' is specified
606  is_undef(u) ? str(rt, " ", rd) : str(rt, " ", rd, " ", u);
607 
608  // individual or common arrowheads
609  da1 = defined_or(a1, d ? a : 0);
610  da2 = defined_or(a2, a);
611 
612  // when text placed over line
613  if ( second(tp) == 0 && !is_empty(dt) )
614  difference()
615  {
616  // remove window from dimension line for text
617  draft_line(l=[pd1, pd2], w=w, s=s, a1=da1, a2=da2);
618 
619  translate( (pd1+pd2)/2 )
620  rotate( [0, 0, ape] )
621  draft_note
622  (
623  note=dt,
624  size=ts,
625  line=[0,0],
626  halign="center",
627  cmh=cmh,
628  cmv=cmv,
629  zp=tp,
630  window=true,
631  layers=layers,
632  $draft_make_3d=false
633  );
634  }
635  else
636  {
637  draft_line(l=[pd1, pd2], w=w, s=s, a1=da1, a2=da2);
638  }
639 
640  if ( !is_empty(dt) )
641  translate( (pd1+pd2)/2 )
642  rotate( [0, 0, ape] )
643  draft_note
644  (
645  note=dt,
646  size=ts,
647  line=[0,0],
648  halign="center",
649  cmh=cmh,
650  cmv=cmv,
651  zp=tp,
652  window=false,
653  layers=layers,
654  $draft_make_3d=false
655  );
656  }
657 }
658 
659 //! Construct a angular dimension arc.
660 /***************************************************************************//**
661  \param o <point-2d> The arc center point.
662  \param r <decimal> The arc radius length.
663 
664  \param v1 <line-2d | decimal> The arc initial angle.
665  A 2d line, vector, or decimal angle.
666  \param v2 <line-2d | decimal> The arc terminal angle.
667  A 2d line, vector, or decimal angle.
668 
669  \param fn <integer> The number of [facets].
670  \param cw <boolean> Sweep clockwise along arc from the head of
671  vector \p v1 to the head of vector \p v2 when \p cw =
672  \b true, and counter clockwise when \p cw = \b false.
673 
674  \param t <string | string-list> A single or multi-line text string
675  that overrides the measured angle.
676  \param u <string> The units for the measured angle.
677  One of the predefined in \ref units_angle.
678 
679  \param e <decimal | decimal-list-2> The extension line to radius ratio.
680  A list [e1, e2] of decimals or a single decimal for (e1=e2).
681  \param es <integer | integer-list> The extension line [style].
682 
683  \param w <decimal> The arc weight.
684  \param s <integer | integer-list> The arc [style].
685 
686  \param a <integer | integer-list-5> The arrowhead style applied to
687  both ends. A single integer selects the style; a list of up
688  to 5 fields customises fill, side, length, and angle; see
689  the field table in [arrow].
690  \param a1 <integer | integer-list-5> The arrowhead 1 override;
691  when set, takes precedence over \p a for endpoint 1. See
692  the field table in [arrow].
693  \param a2 <integer | integer-list-5> The arrowhead 2 override;
694  when set, takes precedence over \p a for endpoint 2. See
695  the field table in [arrow].
696 
697  \param off <decimal> The dimension arc offset.
698 
699  \param ts <decimal-list-3> The text size specification
700  <width, line-height, heading-height>. Sets the note box cell
701  size in units of \p cmh / \p cmv. Passed directly to
702  \ref draft_note() as its \p size parameter.
703  \param tp <decimal-list-2..4> The text placement point.
704  A list [tpx, tpy] of decimals that scales the note box
705  position along each axis (−1=left/bottom, +1=right/top).
706  An optional 3rd element \c tp[2] offsets the text pivot
707  angle (degrees) along the arc, and an optional 4th element
708  \c tp[3] adds a rotation offset in degrees applied on top
709  of the computed text angle.
710  \param rm <integer> The measurement rounding mode.
711  One of: 0=none, 1=[round_d], and 2=[round_s].
712 
713  \param cmh <decimal> The horizontal width minimum unit cell size.
714  \param cmv <decimal> The vertical height minimum unit cell size.
715 
716  \param layers <string-list> The list of drafting layer names to
717  render this object on. Defaults to the "dim"; rendered with
718  dimension annotations. See \ref draft_layers_show and the
719  layer [conventions].
720 
721  \details
722 
723  \amu_eval ( html_image_w=256 latex_image_w="1.50in" object=draft_dim_angle ${object_diagram_2d} )
724 
725  \amu_eval(${group_references})
726 *******************************************************************************/
727 module draft_dim_angle
728 (
729  o = origin2d,
730  r = 1,
731 
732  v1,
733  v2,
734 
735  fn,
736  cw = false,
737 
738  t,
739  u,
740 
741  e = _draft_get_config("dim-angle-extension-ratio"),
742  es = _draft_get_config("dim-angle-extension-style"),
743 
744  w = _draft_get_config("dim-angle-weight"),
745  s = _draft_get_config("dim-angle-style"),
746  a = _draft_get_config("dim-angle-arrow"),
747 
748  a1,
749  a2,
750 
751  off = _draft_get_config("dim-offset"),
752 
753  ts = _draft_get_config("dim-text-size"),
754  tp = _draft_get_config("dim-text-place"),
755  rm = _draft_get_config("dim-round-mode"),
756 
757  cmh = _draft_get_config("dim-cmh"),
758  cmv = _draft_get_config("dim-cmv"),
759 
760  layers = _draft_get_config("layers-dim")
761 )
762 {
763  if (_draft_layers_any_active(layers))
764  _draft_make_3d_if_configured()
765  {
766  // identify measurement reference points at center 'o'
767  mr1 = is_point(v1) ? v1
768  : is_number(v1) ? line_tp(line2d_new(a=v1, p1=o))
769  : line_tp(line2d_new(v=v1, p1=o));
770  mr2 = is_point(v2) ? v2
771  : is_number(v2) ? line_tp(line2d_new(a=v2, p1=o))
772  : line_tp(line2d_new(v=v2, p1=o));
773 
774  // extension line to radius ratio
775  er1 = defined_e_or(e, 0, e);
776  er2 = defined_e_or(e, 1, er1);
777 
778  // extension line end points
779  pe1 = line_tp(line2d_new(m=r, v=[o, mr1], p1=o));
780  pe2 = line_tp(line2d_new(m=r, v=[o, mr2], p1=o));
781 
782  // dimension text angle and position
783  dta = angle_ll(x_axis2d_uv, cw ? [mr1, mr2] : [mr2, mr1], false)
784  + defined_or(third(tp), 0);
785  dtp = line_tp(line2d_new(m=r-off, a=dta+90, p1=o));
786 
787  //
788  // draft
789  //
790 
791  // extension lines (back towards center point)
792  draft_line(l=line2d_new(m=r*er1, v=[mr1, o], p1=pe1), w=w/2, s=es);
793  draft_line(l=line2d_new(m=r*er2, v=[mr2, o], p1=pe2), w=w/2, s=es);
794 
795  // dimension text
796  dt = is_defined(t) ? t
797  : let
798  (
799  // measure angle between reference points
800  ma = cw ?
801  angle_ll([o, mr2], [o, mr1], false)
802  : angle_ll([o, mr1], [o, mr2], false),
803 
804  // use specified units 'u'
805  au = is_undef(u) ? ma
806  : angle(ma, from=angle_unit_base, to=u),
807 
808  // rounding: [mode:0, digits]
809  rs = defined_e_or(rm, 0, 0),
810 
811  rd = rs == 1 ? round_d(au, defined_e_or(rm, 1, 2))
812  : rs == 2 ? round_s(au, defined_e_or(rm, 1, 3))
813  : au
814  )
815  // add units id when 'u' is specified
816  is_undef(u) ? str(rd) : str(rd, " ", u);
817 
818  // individual or common arrowheads
819  da1 = defined_or(a1, a);
820  da2 = defined_or(a2, a);
821 
822  // when text placed over line
823  if ( second(tp) == 0 && !is_empty(dt) )
824  difference()
825  {
826  // remove window from dimension line for text
827  draft_arc(r=r-off, o=o, v1=[o, pe1], v2=[o, pe2], fn=fn, cw=cw, w=w, s=s, a1=da1, a2=da2);
828 
829  translate( dtp )
830  rotate( [0, 0, dta + defined_or(tp[3], 0)] )
831  draft_note
832  (
833  note=dt,
834  size=ts,
835  line=[0,0],
836  halign="center",
837  cmh=cmh,
838  cmv=cmv,
839  zp=tp,
840  window=true,
841  layers=layers,
842  $draft_make_3d=false
843  );
844  }
845  else
846  {
847  draft_arc(r=r-off, o=o, v1=[o, pe1], v2=[o, pe2], fn=fn, cw=cw, w=w, s=s, a1=da1, a2=da2);
848  }
849 
850  if ( !is_empty(dt) )
851  translate( dtp )
852  rotate( [0, 0, dta + defined_or(tp[3], 0)] )
853  draft_note
854  (
855  note=dt,
856  size=ts,
857  line=[0,0],
858  halign="center",
859  cmh=cmh,
860  cmv=cmv,
861  zp=tp,
862  window=false,
863  layers=layers,
864  $draft_make_3d=false
865  );
866  }
867 }
868 
869 //! Construct a center mark dimension cross.
870 /***************************************************************************//**
871  \param o <point-2d> The center point.
872 
873  \param r <decimal> A circular arc radius.
874 
875  \param v <line-2d | decimal> The cross rotation angle.
876  A 2d line, vector, or decimal angle.
877  \param l <decimal> The cross line length.
878 
879  \param e <decimal | decimal-list-4> The length of the extension
880  lines. A list [e1, e2, e3, e4] of decimals or a single
881  decimal for (e1=e2=e3=e4).
882  \param es <integer | integer-list> The extension line [style].
883  Defaults to \c dim-center-extension-style from \ref
884  draft_config_map.
885 
886  \param w <decimal> The line weight.
887  \param s <integer | integer-list> The line [style].
888 
889  \param layers <string-list> The list of drafting layer names to
890  render this object on. Defaults to the "dim"; rendered with
891  dimension annotations. See \ref draft_layers_show and the
892  layer [conventions].
893 
894  \details
895 
896  \amu_eval ( html_image_w=512 latex_image_w="3.00in" object=draft_dim_center ${object_diagram_2d} )
897 
898  \amu_eval(${group_references})
899 *******************************************************************************/
900 module draft_dim_center
901 (
902  o = origin2d,
903 
904  r,
905 
906  v = 0,
907  l = _draft_get_config("dim-center-length"),
908 
909  e,
910  es = _draft_get_config("dim-center-extension-style"),
911 
912  w = _draft_get_config("dim-center-weight"),
913  s = _draft_get_config("dim-center-style"),
914 
915  layers = _draft_get_config("layers-dim")
916 )
917 {
918  if (_draft_layers_any_active(layers))
919  _draft_make_3d_if_configured()
920  {
921  // alignment angle
922  aa = is_number(v) ? v : angle_ll(x_axis2d_uv, v);
923 
924  //
925  // draft
926  //
927 
928  // center
929  for ( q = [0,1] )
930  {
931  la = aa + 90*q;
932  p1 = o - l * [cos(la), sin(la)];
933 
934  draft_line(l=line2d_new(m=l*2, a=la, p1=p1), w=w, s=s);
935  }
936 
937  // radius
938  if ( is_defined(r) )
939  for ( q = [0:3] )
940  {
941  la = aa + 90*q;
942  p1 = o + (r-l) * [cos(la), sin(la)]; // radius
943  p2 = o + (r-l/2)/2 * [cos(la), sin(la)]; // mid
944 
945  draft_line(l=line2d_new(m=l*2, a=la, p1=p1), w=w, s=s);
946  draft_line(l=line2d_new(m=l/2, a=la, p1=p2), w=w, s=s);
947  }
948 
949  // individual extensions
950  rs = is_defined(r) ? (r + 2*l) : (2*l); // radial start distance
951  dl = defined_e_or(e, 0, e); // default length
952 
953  if ( is_defined(e) )
954  for ( q = [0:3] )
955  {
956  la = aa + 90*q;
957  p1 = o + rs * [cos(la), sin(la)]; // start point
958  el = defined_e_or(e, q, dl) - rs; // individual lengths
959 
960  if (el > 0)
961  draft_line(l=line2d_new(m=el, a=la, p1=p1), w=w, s=es);
962  }
963 
964  }
965 }
966 
967 //! @}
968 
969 //! @}
970 
971 //----------------------------------------------------------------------------//
972 // openscad-amu auxiliary scripts
973 //----------------------------------------------------------------------------//
974 
975 /*
976 BEGIN_SCOPE diagram;
977  BEGIN_OPENSCAD;
978  include <omdl-base.scad>;
979  include <transforms/base_cs.scad>;
980  include <tools/common/polytope.scad>;
981  include <tools/2d/drafting/draft-base.scad>;
982 
983  object = "draft_dim_leader";
984 
985  if (object == "draft_dim_leader") {
986  draft_dim_leader (l1=25, v2=0, t="1");
987  }
988 
989  if (object == "draft_dim_line") {
990  draft_dim_line (p1=[0,0], p2=[100,0], u="cm");
991  }
992 
993  if (object == "draft_dim_radius") {
994  draft_arc (r=50, v1=90, s=2);
995  draft_dim_radius (r=50, v=45, u="cm", a1=[4,0,2]);
996  }
997 
998  if (object == "draft_dim_angle") {
999  draft_dim_angle (r=50, v1=0, v2=angle(pi/4+pi/16,"r"), u="dms");
1000  }
1001 
1002  if (object == "draft_dim_center") {
1003  draft_arc (r=25, w=1/4);
1004  draft_dim_center (r=25, l=5, e=[100,0,100,0]);
1005  }
1006  END_OPENSCAD;
1007 
1008  BEGIN_MFSCRIPT;
1009  include --path "${INCLUDE_PATH}" {var_init,var_gen_svg}.mfs;
1010 
1011  defines name "objects" define "object"
1012  strings "
1013  draft_dim_leader
1014  draft_dim_line
1015  draft_dim_radius
1016  draft_dim_angle
1017  draft_dim_center
1018  ";
1019  variables add_opts_combine "objects";
1020  variables add_opts "--viewall --autocenter";
1021 
1022  include --path "${INCLUDE_PATH}" scr_make_mf.mfs;
1023  END_MFSCRIPT;
1024 END_SCOPE;
1025 */
1026 
1027 //----------------------------------------------------------------------------//
1028 // end of file
1029 //----------------------------------------------------------------------------//
origin2d
<point-2d> The origin point coordinate in 2d Euclidean space.
Definition: constants.scad:407
x_axis2d_uv
<vector-2d> The unit vector of the positive x-axis in 2d Euclidean space.
Definition: constants.scad:410
function line_tp(l)
Return the terminal point of a line or vector.
function angle_ll(l1, l2, s=true)
Compute the angle between two lines or vectors in a 3d or 2d-space.
function is_point(v)
Test if a value defines a point.
function line2d_new(m=1, a=0, p1=origin2d, p2, v)
Construct a 2 dimensional directed line.
function point_closest_pl(p, l)
Compute the coordinates of the closest point on a line to a given point.
function distance_pp(p1, p2)
Compute the distance between two points.
function defined_e_or(v, i, d)
Returns an element from an iterable if it exists, or a default value if not.
function third(v)
Return the third element of an iterable value.
function second(v)
Return the second element of an iterable value.
function is_empty(v)
Test if an iterable value is empty.
function round_d(v, d=6)
Round a list of numbers to a fixed number of decimal point digits.
function round_s(v, d=6)
Round a list of numbers to a fixed number of significant figures.
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 is_number(v)
Test if a value is a number.
module draft_line(l=x_axis2d_ul, w=1, s=1, a1=0, a2=0)
Draft a line with configurable style and optional arrowheads.
module draft_dim_radius(o=origin2d, p, r=1, v, t, u, d=false, w=_draft_get_config("dim-radius-weight"), s=_draft_get_config("dim-radius-style"), a=_draft_get_config("dim-radius-arrow"), a1, a2, off=_draft_get_config("dim-offset"), ts=_draft_get_config("dim-text-size"), tp=_draft_get_config("dim-text-place"), rm=_draft_get_config("dim-round-mode"), cmh=_draft_get_config("dim-cmh"), cmv=_draft_get_config("dim-cmv"), layers=_draft_get_config("layers-dim"))
Construct a radial dimension line.
Definition: dimension.scad:662
module draft_dim_line(p1=origin2d, p2=origin2d, v1, v2, t, u, d=_draft_get_config("dim-line-distance"), e=_draft_get_config("dim-line-extension-length"), es=_draft_get_config("dim-line-extension-style"), w=_draft_get_config("dim-line-weight"), s=_draft_get_config("dim-line-style"), a=_draft_get_config("dim-line-arrow"), a1, a2, off=_draft_get_config("dim-offset"), ts=_draft_get_config("dim-text-size"), tp=_draft_get_config("dim-text-place"), rm=_draft_get_config("dim-round-mode"), cmh=_draft_get_config("dim-cmh"), cmv=_draft_get_config("dim-cmv"), layers=_draft_get_config("layers-dim"))
Construct a dimension line between two points.
Definition: dimension.scad:428
$draft_make_3d
<boolean> Extrude 2D drafted constructions to 3D.
Definition: config.scad:97
module draft_dim_angle(o=origin2d, r=1, v1, v2, fn, cw=false, t, u, e=_draft_get_config("dim-angle-extension-ratio"), es=_draft_get_config("dim-angle-extension-style"), w=_draft_get_config("dim-angle-weight"), s=_draft_get_config("dim-angle-style"), a=_draft_get_config("dim-angle-arrow"), a1, a2, off=_draft_get_config("dim-offset"), ts=_draft_get_config("dim-text-size"), tp=_draft_get_config("dim-text-place"), rm=_draft_get_config("dim-round-mode"), cmh=_draft_get_config("dim-cmh"), cmv=_draft_get_config("dim-cmv"), layers=_draft_get_config("layers-dim"))
Construct a angular dimension arc.
Definition: dimension.scad:888
module draft_dim_center(o=origin2d, r, v=0, l=_draft_get_config("dim-center-length"), e, es=_draft_get_config("dim-center-extension-style"), w=_draft_get_config("dim-center-weight"), s=_draft_get_config("dim-center-style"), layers=_draft_get_config("layers-dim"))
Construct a center mark dimension cross.
module draft_arc(r=1, o=origin2d, v1=x_axis2d_uv, v2=x_axis2d_uv, fn, cw=true, w=1, s=1, a1=0, a2=0)
Draft an arc with configurable style and optional arrowheads.
module draft_note(head, note, size, line, halign="left", cmh=_draft_get_config("note-cmh"), cmv=_draft_get_config("note-cmv"), zp=0, window=false, layers=_draft_get_config("layers-note"))
Construct a text note with optional heading and border.
module draft_dim_leader(p=origin2d, v1=30, l1=_draft_get_config("dim-leader-length"), v2, l2, h, t, ts, tp, tr, ta="center", line, w=_draft_get_config("dim-leader-weight"), s=_draft_get_config("dim-leader-style"), a=_draft_get_config("dim-leader-arrow"), off=_draft_get_config("dim-offset"), cmh=_draft_get_config("dim-cmh"), cmv=_draft_get_config("dim-cmv"), window=false, layers=_draft_get_config("layers-dim"))
Construct a dimension leader line at a point.
Definition: dimension.scad:251
function angle(a, from=angle_unit_default, to=angle_unit_base)
Convert an angle value from one unit to another.
angle_unit_base
Definition: angle.scad:741
function length(v, from=length_unit_default, to=length_unit_base, d=1)
Convert a length value from one unit to another, with optional dimensional scaling.
length_unit_base
Definition: length.scad:982