%%%% stlltns.lmc %%%% Created by Laurence D. Finston (LDF) Wed Dec 29 19:33:34 CET 2010 %%%% $Id: stlltns.lmc,v 1.11 2022/12/16 14:05:14 lfinsto1 Exp $ %% * (1) Copyright and License. %%%% This file is part of GNU 3DLDF, a package for three-dimensional drawing. %%%% Copyright (C) 2010, 2011, 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: December 29, 2010 %% Last updated: January 14, 2011 %% * (1) Macros %% ** (2) macro generate_pattern %% This macro can be used to generate multiple patterns using parameters. %% I have now figured out why it doesn't work to pass a `picture' %% to a macro as a typed parameter (from `scanprsf.web'): %% %% "A `picture' can't be passed to a macro as a typed parameter, %% because |:=| is used to assign to the variable used within the macro. %% In addition, if a `point' (and presumably any other data type without a default value) %% is passed as a typed parameter, an assignment to this object must already have been %% performed. Otherwise, the assignment to the variable within the macro will fail." %% %% I've added a "TODO" note to myself to fix these problems. %% %% LDF 2010.12.29. macro generate_pattern; def generate_pattern (main_picture, auxiliary_picture) {numeric inner_triangle_length, numeric inner_triangle_width, numeric segments, numeric outer_length_scale_value, numeric outer_width_scale_value, numeric between_length_scale_value, numeric between_width_scale_value, numeric between_distance_value, boolean do_between_quadrilaterals} := point p[]; path q[]; transform t[]; circle c[]; numeric division_angle; division_angle := 360 / segments; numeric a; numeric b; numeric c; p0 := origin; p1 := p0 shifted (0, 0, inner_triangle_length); p2 := p0 shifted (0, 0, -inner_triangle_length); p3 := p0 shifted (inner_triangle_width, 0); p4 := p0 shifted (-inner_triangle_width, 0); % if do_labels: % %dotlabel.top("$p_{0}$", p0) main_picture; % dotlabel.top("$p_{1}$", p1) main_picture; % dotlabel.bot("$p_{2}$", p2) main_picture; % dotlabel.rt("$p_{3}$", p3) main_picture; % dotlabel.lft("$p_{4}$", p4) main_picture; % fi; q0 := p1 -- p4 -- p2 -- p3 -- cycle; %% main_picture is added to current_picture before `endfig'. %% Drawing the quadrilaterals on main_picture ensures that the help lines aren't drawn %% over them. %% LDF 2010.12.17. draw q0 on_picture main_picture; p5 := mediate(p1, p4); p6 := mediate(p4, p2); p7 := mediate(p2, p3); p8 := mediate(p3, p1); p9 := mediate(p3, p4); % if do_labels: % dotlabel.ulft("$p_{5}$", p5) main_picture; % dotlabel.llft("$p_{6}$", p6) main_picture; % dotlabel.lrt("$p_{7}$", p7) main_picture; % dotlabel.urt("$p_{8}$", p8) main_picture; % label("$p_{9}$", p9) main_picture; % fi; %% *** (3) Outer quadrilateral q1 := q0 scaled (outer_width_scale_value, 0, outer_length_scale_value); q2 := q1; t0 := identity shifted by (p1 - get_point 2 q1); shift t0 (0, 0, .25); p10 := p9; q2 *= p10 *= t0; % if do_labels: % dotlabel.top("$p_{10}$", p10) main_picture; % % for i = 0 upto 3: % label.top(i, get_point (i) q2) main_picture; % endfor; % fi; a := zpart get_point 2 q2; c0 := unit_circle scaled (a, 0, a); draw c0 dashed evenly with_color dark_grey on_picture auxiliary_picture; a := magnitude(get_point 1 q2); c1 := unit_circle scaled (a, 0, a); draw c1 dashed evenly with_color dark_grey on_picture auxiliary_picture; a := magnitude(get_point 0 q2); c2 := unit_circle scaled (a, 0, a); draw c2 dashed evenly with_color dark_grey on_picture auxiliary_picture; draw q2 on_picture main_picture; draw get_point 0 q2 -- get_point 2 q2 dashed evenly with_color dark_grey on_picture auxiliary_picture; q3 := q2; for i = 1 upto segments - 1: rotate q3 (0, division_angle); draw q3 on_picture main_picture; draw get_point 0 q3 -- get_point 2 q3 dashed evenly with_color dark_grey on_picture auxiliary_picture; % draw get_point 1 q3 -- get_point 3 q3 dashed evenly with_color dark_grey on_picture auxiliary_picture; endfor; % message "c0:"; % show c0; % message "c1:"; % show c1; % message "c2:"; % show c2; %% *** (3) Middle quadrilateral q4 := q1 scaled (.75, 0, .75); shift q4 by (p10 - p9); draw q4 on_picture main_picture; q5 := q4; for i = 1 upto segments - 1: rotate q5 (0, division_angle); draw q5 on_picture main_picture; endfor; %% *** (3) Inner quadrilateral q6 := q1 scaled (.4, 0, .4); shift q6 by (p10 - p9); draw q6 on_picture main_picture; q7 := q6; for i = 1 upto segments - 1: rotate q7 (0, division_angle); draw q7 on_picture main_picture; endfor; %% *** (3) Inner quadrilateral at center q8 := q0 scaled (.5, 0, .5); draw q8 on_picture main_picture; %% *** (3) Outer between quadrilateral if do_between_quadrilaterals: q9 := q0 scaled (between_width_scale_value, 0, between_length_scale_value); q10 := q9; t0 := identity rotated (0, .5division_angle); q10 *= t0; for i = 0 upto 3: p[i + 11] := get_point (i) q10; endfor; p15 := mediate(p12, p14); a := get_radius c2; b := get_radius c1; c := a - b; c *= between_distance_value; c += b; p16 := (p9 shifted (0, 0, c)) rotated (0, .5division_angle); t0 := identity shifted by (p16 - p15); p11 *= p12 *= p13 *= p14 *= p15 *= q10 *= t0; draw q10 on_picture main_picture; % dotlabel.top("$p_{11}$", p11) main_picture; % dotlabel.lft("$p_{12}$", p12) main_picture; % dotlabel.bot("$p_{13}$", p13) main_picture; % dotlabel.rt("$p_{14}$", p14) main_picture; % dotlabel.top("$p_{15}$", p15) main_picture; % dotlabel.bot("$p_{16}$", p16) main_picture; draw get_point 0 q10 -- get_point 2 q10 dashed evenly with_color dark_grey on_picture auxiliary_picture; q11 := q10; for i = 1 upto segments - 1: rotate q11 (0, division_angle); draw q11 on_picture main_picture; draw get_point 0 q11 -- get_point 2 q11 dashed evenly with_color dark_grey on_picture auxiliary_picture; endfor; %% *** (3) Circle at outer edge of outer between quadrilateral a := magnitude(p11 - p9); c3 := unit_circle scaled (a, 0, a); draw c3 dashed evenly with_color dark_grey on_picture auxiliary_picture; %% *** (3) Circle at center of outer between quadrilateral a := magnitude(p15 - p9); c4 := unit_circle scaled (a, 0, a); draw c4 dashed evenly with_color dark_grey on_picture auxiliary_picture; %% *** (3) Middle between quadrilateral q12 := q9 scaled (.75, 0, .75); rotate q12 (0, .5division_angle); shift q12 by (p15 - p9); draw q12 on_picture main_picture; q13 := q12; for i = 1 upto segments - 1: rotate q13 (0, division_angle); draw q13 on_picture main_picture; endfor; %% *** (3) Inner between quadrilateral q14 := q1 scaled (.4, 0, .4); rotate q14 (0, .5division_angle); shift q14 by (p15 - p9); draw q14 on_picture main_picture; q15 := q14; for i = 1 upto segments - 1: rotate q15 (0, division_angle); draw q15 on_picture main_picture; endfor; fi; %% if do_between_quadrilaterals %% *** (3) Crosshair at center a := .75; draw (-a, 0) -- (a, 0) dashed evenly on_picture auxiliary_picture; % dark_grey draw (0, 0, -a) -- (0, 0, a) dashed evenly on_picture auxiliary_picture; %% *** (3) enddef; %% ** (2) Macro generate_star macro generate_star; def generate_star (V) {bool do_labels, bool do_double_lines, bool do_help_lines, bool do_cutout, numeric diam, numeric length_zero, numeric rotation_zero, numeric length_one, numeric rotation_one, numeric divisions, numeric center_offset, numeric double_line_offset, numeric scale_factor} = %% *** (3) % message "Entering generate_star:"; % message "diam:"; % show diam; length_zero *= diam; %% Length of long triangle % message "length_zero:"; % show length_zero; % message "rotation_zero:"; % show rotation_zero; length_one *= diam; %% Length of short triangle % message "length_one:"; % show length_one; % message "rotation_one:"; % show rotation_one; % message "divisions:"; % show divisions; % message "center_offset:"; % show center_offset; % message "scale_factor:"; % show scale_factor; %% Cutouts require double lines. LDF 2011.01.14. if do_cutout: do_double_lines := true; fi; %% *** (3) circle c[]; point p[]; path q[]; picture label_picture; transform t[]; pen thin_pen; thin_pen := pencircle scaled (.33mm, .33mm, .33mm); pen big_pen; big_pen := pencircle scaled (1mm, 1mm, 1mm); %% *** (3) set c0 with_diameter diam with_point_count 64; draw c0 on_picture v; p0 := (2.5, 0, 0); if do_labels: % dotlabel.rt("$p_{0}$", p0) label_picture; fi; %% **** (4) First long triangle p1 := p0 shifted length_zero; p2 := p1 shifted (0, 1); p3 := p0 rotated_around (p1, p2) rotation_zero; bool_point_vector bpv; bpv := c0 intersection_points (p1 -- p3); p4 := bpv[0]; p5 := bpv[1]; if is_invalid p4 and is_invalid p5: message "p4 and p5 are invalid. Quitting"; endfig; end; elseif is_invalid p4: p4 := p5; elseif is_invalid p5: ; else: % message "p4 and p5 are both valid."; if xpart p5 >= xpart p4: p4 := p5; fi; fi; p5 := p4 rotated_around (p1, p0) 180; if do_labels: dotlabel.top("$p_{1}$", p1) label_picture; dotlabel.bot("$p_{3}$", p3) label_picture; dotlabel.lft("$p_{4}$", p4) label_picture; dotlabel.rt("$p_{5}$", p5) label_picture; fi; q0 := p4 -- p1 -- p5; draw q0 on_picture v; q1 := p0 -- p1; bool_point bp; set c1 with_diameter .5cm with_point_count 64; draw c1 with_color dark_grey dashed evenly on_picture v; if do_double_lines: p24 := p0 shifted (0, 0, .5 * double_line_offset); p25 := p0 shifted (0, 0, -.5 * double_line_offset); p26 := p24 shifted (1, 0); p27 := p25 shifted (1, 0); p28 := (p24 -- p26) intersection_point (p5 -- p1); p29 := (p25 -- p27) intersection_point (p4 -- p1); draw p24 -- p28 on_picture v; draw p25 -- p29 on_picture v; bpv := c1 intersection_points (p26 -- p24); p30 := bpv[0]; p31 := bpv[1]; if xpart p30 <= xpart p31: p30 := p31; fi; bpv := c1 intersection_points (p25 -- p27); p31 := bpv[0]; p32 := bpv[1]; if xpart p31 <= xpart p32: p31 := p32; fi; draw p30 -- p24 on_picture v; draw p31 -- p25 on_picture v; % if do_labels: % dotlabel.urt("$p_{24}$", p24) label_picture; % dotlabel.lrt("$p_{25}$", p25) label_picture; % dotlabel.top("$p_{26}$", p26) label_picture; % dotlabel.bot("$p_{27}$", p27) label_picture; % dotlabel.top("$p_{28}$", p28) label_picture; % dotlabel.bot("$p_{29}$", p29) label_picture; % % dotlabel.top("$p_{30}$", p30) label_picture; % % dotlabel.bot("$p_{31}$", p31) label_picture; % fi; else: draw q1 on_picture v; fi; p20 := unit_vector(p4) / center_offset; p21 := unit_vector(p5) / center_offset; p22 := unit_vector(p0) / center_offset; draw p4 -- p20 on_picture v; draw p5 -- p21 on_picture v; %% **** (4) First short triangle p6 := p0 shifted (length_one, 0); p7 := p6 shifted (0, 1); p8 := p0 rotated_around (p6, p7) rotation_one; bpv := c0 intersection_points (p6 -- p8); p9 := bpv[0]; p10 := bpv[1]; if is_invalid p9 and is_invalid p10: message "p9 and p10 are invalid. Quitting"; endfig; end; elseif is_invalid p9: p9 := p10; elseif is_invalid p10: ; else: % message "p9 and p10 are both valid."; if xpart p10 >= xpart p9: p9 := p10; fi; fi; p10 := p9 rotated_around (p0, p6) 180; q2 := p9 -- p6 -- p10; t0 := identity rotated (0, (360 / divisions)); p11 := p0; q2 *= p6 *= p9 *= p10 *= p11 *= t0; draw q2 on_picture v; q3 := p11 -- p6; if do_double_lines: draw q3 dashed evenly with_color dark_grey with_pen thin_pen on_picture v; else: draw q3 on_picture v;% with_color cyan; fi; if do_labels: dotlabel.rt("$p_{6}$", p6) label_picture; dotlabel.rt("$p_{8}$", p8) label_picture; dotlabel.rt("$p_{9}$", p9) label_picture; dotlabel.lft("$p_{10}$", p10) label_picture; dotlabel.rt("$p_{11}$", p11) label_picture; fi; p23 := unit_vector(p11) / center_offset; %% ***** (5) if do_double_lines: %% ****** (6) a := .5 * double_line_offset; p33 := mediate(p11, p6); p34 := p33 shifted (0, 1); p35 := ((a * unit_vector(p6 - p33)) shifted by p33) rotated_around (p33, p34) 90; p36 := ((a * unit_vector(p6 - p33)) shifted by p33) rotated_around (p33, p34) -90; p37 := p35 shifted by (p6 - p33); p38 := p36 shifted by (p6 - p33); p39 := (p35 -- p37) intersection_point (p6 -- p10); p40 := (p36 -- p38) intersection_point (p5 -- p6); bpv := c0 intersection_points (p35 -- p37); p41 := bpv0; p42 := bpv1; if xpart p42 >= xpart p41: p41 := p42; fi; p42 := p41 rotated_around (p11, p6); bpv := c1 intersection_points (p35 -- p37); p43 := bpv0; p44 := bpv1; if xpart p44 >= xpart p43: p43 := p44; fi; p44 := p43 rotated_around (p11, p6); draw p43 -- p39 on_picture v; draw p44 -- p40 on_picture v; draw p11 -- p23 with_color dark_grey with_pen thin_pen dashed evenly on_picture v; set c2 with_diameter (diam - 2 * double_line_offset) with_point_count 64; %draw c2 dashed evenly with_color dark_grey on_picture v; p87 := .5 * p5; p88 := p87 shifted (0, 1); p89 := ((double_line_offset * unit_vector(p5)) shifted by p87) rotated_around (p87, p88) -90; p90 := mediate(p87, p5); p91 := p89 shifted by (p90 - p87); bpv := c1 intersection_points (p89 -- p91); p92 := bpv0; p93 := bpv1; if xpart p93 >= xpart p92: p92 := p93; fi; bpv := c2 intersection_points (p89 -- p91); p93 := bpv0; p94 := bpv1; if xpart p94 >= xpart p93: p93 := p94; fi; bpv := c2 intersection_points (p26 -- p24); p94 := bpv0; p95 := bpv1; if xpart p95 >= xpart p94: p94 := p95; fi; p95 := (p24 -- p26) intersection_point (p91 -- p89); t0 := identity rotated_around (origin, p1); p96 := p95 * t0; p97 := p89 * t0; p98 := p91 * t0; p99 := p93 * t0; p100 := p94 * t0; q19 += ..; q19 += p93; point temp_pt; temp_pt := p93; forever: rotate temp_pt (0, -5); exit_if zpart temp_pt <= zpart p94; q19 += temp_pt; endfor; q19 += p94; q20 := p95 -- p93 .. q19 .. p94 -- p95; q20 += cycle; q21 := q20 * t0; if do_cutout: filldraw q20 with_fill_color grey on_picture v; filldraw q21 with_fill_color grey on_picture v; else: draw q20 with_fill_color dark_grey on_picture v; draw q21 with_fill_color dark_grey on_picture v; fi; %% ****** (6) p101 := mediate(p1, p5); p102 := p101 shifted (0, 1); p103 := ((double_line_offset * (unit_vector(p1 - p5))) shifted by p101) rotated_around (p101, p102) -90; p104 := mediate(p1, p5, 3/4); p105 := p103 shifted by (p104 - p101); bpv := c0 intersection_points (p103 -- p105); p106 := bpv0; p107 := bpv1; if xpart p107 >= xpart p106: p106 := p107; fi; p107 := (p106 -- p103) intersection_point (p24 -- p26); q22 += ..; q22 += p106; temp_pt := p106; forever: rotate temp_pt (0, -5); exit_if zpart temp_pt <= zpart p24; q22 += temp_pt; endfor; q22 += p24; q23 := p24 -- p107 -- p106 .. q22 .. p24; q23 += cycle; q24 := q23 * t0; if do_cutout: filldraw q23 with_fill_color grey on_picture v; filldraw q24 with_fill_color grey on_picture v; else: draw q23 on_picture v; draw q24 on_picture v; fi; %% ****** (6) p108 := mediate(p10, p6); p109 := p108 shifted (0, 1); p110 := ((double_line_offset * unit_vector(p6 - p10)) shifted by p108) rotated_around (p108, p109) -90; p111 := mediate(p10, p6, .25); p112 := p110 shifted by (p111 - p108); bpv := c0 intersection_points (p110 -- p112); p113 := bpv0; p114 := bpv1; if xpart p114 > xpart p113: p113 := p114; fi; p114 := (p113 -- p110) intersection_point (p39 -- p41); q25 += ..; q25 += p113; temp_pt := p113; forever: rotate temp_pt (0, -5); exit_if zpart temp_pt <= zpart p41; q25 += temp_pt; endfor; q25 += p41; q26 := p41 -- p114 -- p113 .. q25 .. p41; q26 += cycle; t0 := identity rotated_around (origin, p6); q27 := q26 * t0; bpv := c2 intersection_points (p87 -- p90); p115 := bpv0; p116 := bpv1; if xpart p116 > xpart p115: p115 := p116; fi; bpv := c2 intersection_points (p40 -- p42); p116 := bpv0; p117 := bpv1; if xpart p117 > xpart p116: p116 := p117; fi; q28 += ..; q28 += p115; temp_pt := p115; forever: rotate temp_pt (0, 1); exit_if zpart temp_pt >= zpart p116; q28 += temp_pt; endfor; q28 += p116; %draw q28 with_color blue on_picture v; bpv := c1 intersection_points (p87 -- p115); p117 := bpv0; p118 := bpv1; if xpart p118 > xpart p117: p117 := p118; fi; q29 := p117 -- p115 .. q28 .. p116 -- p117; q29 += cycle; q30 := q29 * t0; if do_cutout: filldraw q26 with_fill_color grey on_picture v; filldraw q27 with_fill_color grey on_picture v; filldraw q29 with_fill_color grey on_picture v; filldraw q30 with_fill_color grey on_picture v; else: draw q26 on_picture v; draw q27 on_picture v; draw q29 on_picture v; draw q30 on_picture v; fi; %% ****** (6) if do_labels: % dotlabel.lft("$p_{33}$", p33) label_picture; % dotlabel.top("$p_{35}$", p35) label_picture; % dotlabel.bot("$p_{36}$", p36) label_picture; % dotlabel.top("$p_{37}$", p37) label_picture; % dotlabel.bot("$p_{38}$", p38) label_picture; % dotlabel.top("$p_{39}$", p39) label_picture; % dotlabel.rt("$p_{40}$", p40) label_picture; % dotlabel.top("$p_{41}$", p41) label_picture; % dotlabel.rt("$p_{42}$", p42) label_picture; % dotlabel.top("$p_{43}$", p43) label_picture; % dotlabel.bot("$p_{44}$", p44) label_picture; dotlabel.rt("$p_{87}$", p87) label_picture; dotlabel.rt("$p_{89}$", p89) label_picture; % dotlabel.rt("$p_{90}$", p90) label_picture; % dotlabel.bot("$p_{91}$", p91) label_picture; % dotlabel.rt("$p_{92}$", p92) label_picture; % dotlabel.bot("$p_{93}$", p93) label_picture; % dotlabel.ulft("$p_{94}$", p94) label_picture; % dotlabel.urt("$p_{95}$", p95) label_picture; % dotlabel.bot("$p_{96}$", p96) label_picture; % dotlabel.bot("$p_{97}$", p97) label_picture; % dotlabel.llft("$p_{98}$", p98) label_picture; % dotlabel.lft("$p_{99}$", p99) label_picture; % dotlabel.llft("$p_{100}$", p100) label_picture; % dotlabel.top("$p_{101}$", p101) label_picture; % dotlabel.bot("$p_{103}$", p103) label_picture; % dotlabel.top("$p_{104}$", p104) label_picture; % dotlabel.bot("$p_{105}$", p105) label_picture; % dotlabel.rt("$p_{106}$", p106) label_picture; % dotlabel.top("$p_{107}$", p107) label_picture; % dotlabel.top("$p_{108}$", p108) label_picture; % dotlabel.bot("$p_{110}$", p110) label_picture; % dotlabel.top("$p_{111}$", p111) label_picture; % dotlabel.bot("$p_{112}$", p112) label_picture; % dotlabel.llft("$p_{113}$", p113) label_picture; % dotlabel.lrt("$p_{114}$", p114) label_picture; % dotlabel.ulft("$p_{115}$", p115) label_picture; % dotlabel.lft("$p_{116}$", p116) label_picture; % dotlabel.lft("$p_{117}$", p117) label_picture; fi; %% ****** (6) else: draw p11 -- p23 on_picture v; fi; %% ***** (5) Cutouts numeric cutout_offset; cutout_offset := .25cm; if do_cutout: p45 := mediate(p5, p1); p46 := p45 shifted (0, 1); p47 := ((cutout_offset * unit_vector(p1 - p45)) shifted p45) rotated_around (p45, p46) 90; p48 := p47 shifted by (p1 - p45); p50 := (p5 -- p6) intersection_point (p47 -- p48); t0 := identity rotated_around (p0, p1); p51 := p50 * t0; p52 := p47 * t0; p53 := p47 shifted by (p1 - p45); p54 := p53 * t0; p55 := p1 shifted (cutout_offset, 0); p56 := (cutout_offset * unit_vector(p1 - p5)) shifted by p5; p57 := p56 shifted by (p6 - p5); p58 := (p56 -- p57) intersection_point (p50 -- p53); p59 := p58 * t0; p60 := p58 rotated_around (p11, p6); p61 := p57 rotated_around (p11, p6); p62 := (cutout_offset * unit_vector(p6 - p11)) shifted by p6; q8 := p59 -- p54 -- p55 -- p53 -- p58 -- p57 -- p62 -- p61 -- p60; p63 := mediate(p56, p45, .125); p64 := mediate(p58, p47, .125); p65 := mediate(p45, p56, 1/16); p66 := mediate(p47, p58, 1/16); p67 := p65 rotated_around (p45, p47); p68 := p66 rotated_around (p45, p47); p69 := mediate(p1, p45, 1/8); p70 := mediate(p53, p47, 1/8); p71 := p65 shifted by (p70 - p68); p72 := p66 shifted by (p70 - p68); q9 := p63 -- p64 -- p66 -- p65 -- cycle; q10 := p67 -- p71 -- p72 -- p68 -- cycle; q11 := p69 -- p1 -- p55 -- p53 -- p70 -- cycle; q12 := q9 rotated_around (p0, p1); q13 := q10 rotated_around (p0, p1); q14 := q11 rotated_around (p0, p1); p73 := mediate(p6, p10); p74 := p73 shifted (0, 1); p75 := (unit_vector(p6 - p10) shifted p73) rotated_around (p73, p74) 90; p76 := (p73 -- p75) intersection_point (p60 -- p61); p77 := (cutout_offset * unit_vector(p6 - p73)) shifted by p73; p78 := p76 shifted by (p77 - p73); t0 := identity rotated_around (p6, p11); p79 := p73 * t0; p80 := p77 * t0; p81 := p78 * t0; p82 := p76 * t0; p83 := mediate(p10, p6, 1/4); p84 := p76 shifted by (p83 - p73); p85 := p83 * t0; p86 := p84 * t0; q15 := p83 -- p73 -- p76 -- p84 -- cycle; q16 := p77 -- p6 -- p62 -- p61 -- p78 -- cycle; q17 := q15 * t0; q18 := q16 * t0; draw q8 on_picture v; for i = 9 upto 18: filldraw q[i] with_fill_color grey on_picture v; endfor; %% ****** (6) Lines on the parts that aren't cut off. These are for orientation %% when cutting out using a straightedge. Otherwise, one often can't tell %% where to stop cutting. %% LDF 2011.01.14. p118 := (double_line_offset * unit_vector(p63 - p64)) shifted by p63; p119 := (double_line_offset * unit_vector(p65 - p66)) shifted by p65; p120 := (double_line_offset * unit_vector(p67 - p68)) shifted by p67; p121 := (double_line_offset * unit_vector(p71 - p72)) shifted by p71; p122 := (double_line_offset * unit_vector(p69 - p70)) shifted by p69; draw p63 -- p118 on_picture v; draw (p63 -- p118) rotated_around (origin, p1) on_picture v; draw p65 -- p119 on_picture v; draw (p65 -- p119) rotated_around (origin, p1) on_picture v; draw p67 -- p120 on_picture v; draw (p67 -- p120) rotated_around (origin, p1) on_picture v; draw p69 -- p122 on_picture v; draw (p69 -- p122) rotated_around (origin, p1) on_picture v; draw p71 -- p121 on_picture v; draw (p71 -- p121) rotated_around (origin, p1) on_picture v; p123 := (double_line_offset * unit_vector(p83 - p84)) shifted by p83; p124 := (double_line_offset * unit_vector(p73 - p76)) shifted by p73; p125 := (double_line_offset * unit_vector(p77 - p78)) shifted by p77; draw p83 -- p123 on_picture v; draw (p83 -- p123) rotated_around (origin, p6) on_picture v; draw p73 -- p124 on_picture v; draw (p73 -- p124) rotated_around (origin, p6) on_picture v; draw p77 -- p125 on_picture v; draw (p77 -- p125) rotated_around (origin, p6) on_picture v; %% ****** (6) if do_labels: %dotlabel.urt("origin", origin) label_picture; % dotlabel.bot("$p_{45}$", p45) label_picture; % dotlabel.top("$p_{47}$", p47) label_picture; % dotlabel.top("$p_{48}$", p48) label_picture; % dotlabel.lft("$p_{50}$", p50) label_picture; % dotlabel.lft("$p_{51}$", p51) label_picture; % dotlabel.rt("$p_{52}$", p52) label_picture; % dotlabel.urt("$p_{53}$", p53) label_picture; % dotlabel.lrt("$p_{54}$", p54) label_picture; % dotlabel.rt("$p_{55}$", p55) label_picture; % dotlabel.llft("$p_{56}$", p56) label_picture; % dotlabel.lrt("$p_{57}$", p57) label_picture; % dotlabel.lft("$p_{58}$", p58) label_picture; % dotlabel.bot("$p_{59}$", p59) label_picture; dotlabel.ulft("$p_{60}$", p60) label_picture; dotlabel.top("$p_{61}$", p61) label_picture; dotlabel.rt("$p_{62}$", p62) label_picture; dotlabel.bot("$p_{63}$", p63) label_picture; dotlabel.urt("$p_{64}$", p64) label_picture; dotlabel.lft("$p_{65}$", p65) label_picture; dotlabel.ulft("$p_{66}$", p66) label_picture; dotlabel.rt("$p_{67}$", p67) label_picture; dotlabel.urt("$p_{68}$", p68) label_picture; dotlabel.bot("$p_{69}$", p69) label_picture; dotlabel.top("$p_{70}$", p70) label_picture; dotlabel.lft("$p_{71}$", p71) label_picture; dotlabel.lft("$p_{72}$", p72) label_picture; dotlabel.bot("$p_{73}$", p73) label_picture; % dotlabel.top("$p_{75}$", p75) label_picture; dotlabel.top("$p_{76}$", p76) label_picture; dotlabel.bot("$p_{77}$", p77) label_picture; dotlabel.top("$p_{78}$", p78) label_picture; dotlabel.lft("$p_{79}$", p79) label_picture; dotlabel.lft("$p_{80}$", p80) label_picture; dotlabel.rt("$p_{81}$", p81) label_picture; dotlabel.rt("$p_{82}$", p82) label_picture; dotlabel.bot("$p_{83}$", p83) label_picture; dotlabel.top("$p_{84}$", p84) label_picture; dotlabel.lft("$p_{85}$", p85) label_picture; dotlabel.urt("$p_{86}$", p86) label_picture; fi; fi; %% ****** (6) %% ***** (5) %% **** (4) Additional triangles t1 := identity rotated (0, ((2 * 360) / divisions)); q4 := q0; q5 := q1; q6 := q2; q7 := q3; p12 := p0; p13 := p4; p14 := p5; p15 := p11; p16 := unit_vector(p12) * get_radius c1; p17 := unit_vector(p13) * get_radius c1; p18 := unit_vector(p14) * get_radius c1; p19 := unit_vector(p15) * get_radius c1; if do_labels: % dotlabel.top("$p_{12}$", p12) label_picture; % dotlabel.lft("$p_{16}$", p16) label_picture; % dotlabel.bot("$p_{17}$", p17) label_picture; % dotlabel.rt("$p_{18}$", p18) label_picture; % dotlabel.top("$p_{19}$", p19) label_picture; fi; draw origin -- p17 on_picture v; for i := 0 upto 3: p19 *= p18 *= p17 *= p16 *= p12 *= p13 *= p14 *= p15 *= q4 *= q5 *= q6 *= q7 *= t1; if do_double_lines: q20 *= q21 *= q23 *= q24 *= q26 *= q27 *= q29 *= q30 *= p38 *= p39 *= p40 *= p41 *= p43 *= p44 *= p30 *= p31 *= p24 *= p25 *= p28 *= p29 *= t1; draw p30 -- p28 on_picture v; draw p31 -- p29 on_picture v; draw p22 -- p1 dashed evenly with_color dark_grey with_pen thin_pen on_picture v; draw p16 -- p12 dashed evenly with_color dark_grey with_pen thin_pen on_picture v; draw q5 dashed evenly with_color dark_grey with_pen thin_pen on_picture v; draw p43 -- p39 on_picture v; draw p44 -- p40 on_picture v; draw q4 on_picture v;% with_color dark_grey; draw q7 dashed evenly with_color dark_grey with_pen thin_pen on_picture v; draw p19 -- p15 dashed evenly with_color dark_grey with_pen thin_pen on_picture v; if do_cutout: filldraw q20 with_fill_color grey on_picture v; filldraw q21 with_fill_color grey on_picture v; filldraw q23 with_fill_color grey on_picture v; filldraw q24 with_fill_color grey on_picture v; filldraw q26 with_fill_color grey on_picture v; filldraw q27 with_fill_color grey on_picture v; filldraw q29 with_fill_color grey on_picture v; filldraw q30 with_fill_color grey on_picture v; else: draw q20 with_fill_color grey on_picture v; draw q21 with_fill_color grey on_picture v; draw q23 with_fill_color grey on_picture v; draw q24 with_fill_color grey on_picture v; draw q26 on_picture v; draw q27 on_picture v; draw q29 on_picture v; draw q30 on_picture v; fi; else: draw p0 -- p22 on_picture v; draw p16 -- p12 on_picture v; draw q5 on_picture v; draw q4 on_picture v;% with_color green; draw q7 on_picture v;% with_color magenta; draw p19 -- p15 on_picture v;% with_color red; fi; if do_cutout: p63 *= p65 *= p67 *= p69 *= p71 *= p73 *= p77 *= p83 *= p118 *= p119 *= p120 *= p121 *= p122 *= p123 *= p124 *= p125 *= q8 *= t1; draw q8 on_picture v; draw p63 -- p118 on_picture v; draw (p63 -- p118) rotated_around (origin, p1) on_picture v; draw p65 -- p119 on_picture v; draw (p65 -- p119) rotated_around (origin, p1) on_picture v; draw p67 -- p120 on_picture v; draw (p67 -- p120) rotated_around (origin, p1) on_picture v; draw p69 -- p122 on_picture v; draw (p69 -- p122) rotated_around (origin, p1) on_picture v; draw p71 -- p121 on_picture v; draw (p71 -- p121) rotated_around (origin, p1) on_picture v; for i = 9 upto 18: q[i] *= t1; filldraw q[i] with_fill_color grey on_picture v; endfor; fi; draw origin -- p17 on_picture v; draw q6 on_picture v; draw p17 -- p13 on_picture v; draw p18 -- p14 on_picture v; endfor; %draw q6 on_picture v; %draw q7 on_picture v; % if do_labels: % rotate label_picture (0, (180 / divisions)); % fi; %% These should probably stay commented-out. LDF 2011.01.12. %% %rotate v (0, 36); %% %rotate v (0, 36); if do_labels: v += label_picture; fi; %% Comment-out for testing. LDF 2011.01.13. rotate v (0, (180 / divisions)); scale v (scale_factor, 0, scale_factor); %% *** (3) enddef; %% ** (2) %% * (1) Emacs-Lisp code for use in indirect buffers when using the %% GNU Emacs editor. The local variable list is not evaluated when an %% indirect buffer is visited, so it's necessary to evaluate the %% following s-expression in order to use the facilities normally %% accessed via the local variables list. %% LDF 2004.02.12. %% (progn (metafont-mode) (outline-minor-mode t) (setq fill-column 80) (ignore '( %% )) (setq outline-regexp "%% [*\f]+")) %% * (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: