%%%% bldelem0.lmc %%%% Created by Laurence D. Finston (LDF) Thu Jul 19 07:28:05 CEST 2012 %%%% $Id: bldelem0.lmc,v 1.7 2022/12/16 14:04:59 lfinsto1 Exp $ %% * (1) Copyright and License. %%%% This file is part of GNU 3DLDF, a package for three-dimensional drawing. %%%% Copyright (C) 2012, 2013, 2014, !%%%% 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023 The Free Software Foundation, Inc. %%%% GNU 3DLDF is free software; you can redistribute it and/or modify %%%% it under the terms of the GNU General Public License as published by %%%% the Free Software Foundation; either version 3 of the License, or %%%% (at your option) any later version. %%%% GNU 3DLDF is distributed in the hope that it will be useful, %%%% but WITHOUT ANY WARRANTY; without even the implied warranty of %%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the %%%% GNU General Public License for more details. %%%% You should have received a copy of the GNU General Public License %%%% along with GNU 3DLDF; if not, write to the Free Software %%%% Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA %%%% GNU 3DLDF is a GNU package. %%%% It is part of the GNU Project of the %%%% Free Software Foundation %%%% and is published under the GNU General Public License. %%%% See the website http://www.gnu.org %%%% for more information. %%%% GNU 3DLDF is available for downloading from %%%% http://www.gnu.org/software/3dldf/LDF.html. %%%% Please send bug reports to Laurence.Finston@gmx.de %%%% The mailing list help-3dldf@gnu.org is available for people to %%%% ask other users for help. %%%% The mailing list info-3dldf@gnu.org is for sending %%%% announcements to users. To subscribe to these mailing lists, send an %%%% email with ``subscribe '' as the subject. %%%% The author can be contacted at: %%%% Laurence D. Finston %%%% c/o Free Software Foundation, Inc. %%%% 51 Franklin St, Fifth Floor %%%% Boston, MA 02110-1301 %%%% USA %%%% Laurence.Finston@gmx.de %% Created: July 19, 2012 %% Last Updated: July 19, 2012 %% *** (1) Macros %% ** (2) crosshair %% Non-typed arguments: %% vv: picture %% ctr: >= 0: subscript for vv, < 0: vv is not an array. %% %% LDF 2012.06.05. macro crosshair; def crosshair (V) {point aa, numeric offset, point bb, point cc} = pen thin_pen; thin_pen := pencircle scaled (.25mm, .25mm, .25mm); transform tt; point A[]; A0 := aa shifted (0, 0, 1); A1 := (offset * unit_vector(cc - bb)) shifted by aa; A2 := A1 rotated_around (aa, A0) 90; A3 := A1 rotated_around (aa, A0) 180; A4 := A1 rotated_around (aa, A0) 270; if is_picture V: draw A1 -- A3 with_pen pencircle scaled (.25mm, .25mm, .25mm) with_pen thin_pen on_picture V; draw A2 -- A4 with_pen pencircle scaled (.25mm, .25mm, .25mm) with_pen thin_pen on_picture V; else: draw A1 -- A3 with_pen pencircle scaled (.25mm, .25mm, .25mm) with_pen thin_pen; draw A2 -- A4 with_pen pencircle scaled (.25mm, .25mm, .25mm) with_pen thin_pen; fi; enddef; %% ** (2) tab macro tab; % t: path (rectangle, circle, etc.) % V: picture (required) % H_OFFSET: numeric variable % HEIGHT: numeric variable % j, k: Points on path % n: amount of mediation used to get offset from the points on the path % r: amount of mediation used to get offset % from the points on the path for the shorter edge. % u: Height of the tab (multiplied by a unit_vector derived from mag) % mag : magnitude (1 or -1) % crosshair_ctr: Number of crosshairs. def tab (t, V, H_OFFSET, HEIGHT) {numeric j, numeric k, numeric n, numeric r, numeric u, numeric crosshair_ctr, numeric mag} := %% *** (3) % message "In tab:"; boolean do_labels; do_labels := false; % true point P[]; pen thin_pen; thin_pen := pencircle scaled (.25mm, .25mm, .25mm); P21 := get_point (j) t; P22 := get_point (k) t; P0 := mediate(get_point (j) t, get_point (k) t, n); P1 := mediate(get_point (k) t, get_point (j) t, n); H_OFFSET := magnitude (P21 - P22) - magnitude (P0 - P1); P3 := mediate(P0, P1); P12 := P3 shifted (0, 0, 1); P13 := (unit_vector(P1 - P0) shifted P3) rotated_around (P3, P12) -90; P14 := (unit_vector(P1 - P0) shifted P3) rotated_around (P3, P12) 90; if mag > 0: P2 := P13; else: P2 := P14; fi; P4 := u * unit_vector(P2 - P3); shift P4 by P3; HEIGHT := magnitude (P4 - P3); P5 := mediate(get_point (j) t, get_point (k) t, r) shifted by (P4 - P3); P6 := mediate(get_point (k) t, get_point (j) t, r) shifted by (P4 - P3); %draw P0 -- P1 with_pen pencircle scaled (.5mm, .5mm, .5mm) with_color red on_picture V; P7 := mediate(P3, P4); P9 := (P7 - P3) shifted P0; P15 := mediate (P0, P5, 5); P16 := mediate (P5, P0, 5); P17 := mediate (P7, P9, 5); P18 := mediate (P9, P7, 5); %% LDF 2012.06.05. Intersection_point fails here, if drawn in x-z plane. %% There's a note in the definition of Point::intersection_point (or possibly %% Point::intersection_points). P10 := (P15 -- P16) intersection_point (P17 -- P18); P19 := mediate (P1, P6, 5); P20 := mediate (P6, P1, 5); P11 := (P18 -- P17) intersection_point (P19 -- P20); draw P0 -- P5 -- P6 -- P1 -- cycle with_color dark_gray with_pen thin_pen on_picture V; draw P10 -- P11 with_color dark_gray with_pen thin_pen on_picture V; draw P3 -- P4 with_color dark_gray with_pen thin_pen on_picture V; %draw P15 -- P16 withcolor red on_picture V; %draw P17 -- P18 withcolor blue on_picture V; %% *** (3) if crosshair_ctr > 0: for i = 1 upto crosshair_ctr: crosshair (V) {mediate(P10, P11, i/(crosshair_ctr + 1)), .1cm, P10, P11}; endfor; fi; % message "unit_vector(P10 - P11):"; % show unit_vector(P10 - P11); % message "unit_vector(P0 - P1):"; % show unit_vector(P0 - P1); pickup pencircle scaled (.25mm, .25mm, .25mm); if do_labels: %dotlabel.rt("$P_0$", P0) V; %dotlabel.llft("$P_1$", P1) V; %dotlabel.top("$P_2$", P2) V; dotlabel.bot("$P_3$", P3) V; dotlabel.top("$P_4$", P4) V; %dotlabel.urt("$P_5$", P5) V; %dotlabel.ulft("$P_6$", P6) V; % dotlabel.rt("$P_7$", P7) V; % dotlabel.top("$P_9$", P9) V; % dotlabel.top("$P_{10}$", P10) V; % dotlabel.top("$P_{11}$", P11) V; % dotlabel.top("$P_{15}$", P15) V; % dotlabel.top("$P_{16}$", P16) V; % dotlabel.top("$P_{17}$", P17) V; % dotlabel.top("$P_{18}$", P18) V; % dotlabel.top("$P_{19}$", P19) V; % dotlabel.top("$P_{20}$", P20) V; % dotlabel.bot("$P_{11}$", P11) V; fi; %% *** (3) enddef; %% ** (2) %% * (1) Local variables for Emacs. %% Local Variables: %% mode:Metafont %% eval:(outline-minor-mode t) %% eval:(read-abbrev-file abbrev-file-name) %% outline-regexp:"%% [*\f]+" %% End: