summaryrefslogtreecommitdiff
path: root/macros/luatex/generic/minim-mp/minim.mp
blob: ed152a018b6487132b2251f1c3b2f45d2093f998 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120

if known minim.mp:
    expandafter endinput fi
minim.mp := 1.6;

% This file only contains code that is not specific to the minim metapost 
% processor. See minim-mp.mp for the wireup of minim-mp’s extensions.

message "Loading general minim extension macros";

% redefine some constants to work with the new numerical engines
numeric mm, cm, pt, pc, dd, cc;
pc = 12 pt; cc = 12 dd; cm = 10 mm;
803 pt = 800; 127 mm = 360; 1157 dd = 1238 pt;
eps := 1/2048; infinity := 64*64-epsilon;

% constants
pi := 355/113;

% shorthands
primarydef p xshifted x = p shifted (x,0) enddef;
primarydef p yshifted y = p shifted (0,y) enddef;

% reverse paths to allow „p & vflip p”
def hflip primary p = if path p: reverse fi p xscaled -1 enddef;
def vflip primary p = if path p: reverse fi p yscaled -1 enddef;

% missing definitions
path fullsquare, unitcircle ;
fullsquare := unitsquare shifted - center unitsquare ;
unitcircle := fullcircle shifted urcorner fullcircle ;

% complement counterclockwise
vardef clockwise primary c =
    if turningnumber c > 0: reverse fi c enddef;

% clipping
vardef clipto text t =
    clip currentpicture to bbox currentpicture
        for c = t: -- c -- cycle endfor -- cycle enddef;
vardef clipout text t =
    clip currentpicture to
        for c = t: c -- cycle -- endfor cycle enddef;
vardef getbounds primary p = % without bboxmargin
    llcorner p -- lrcorner p -- urcorner p -- ulcorner p -- cycle
enddef;

% cmyk colours
cmykcolor cyan, magenta, yellow, key;
cyan    = (1,0,0,0);
magenta = (0,1,0,0);
yellow  = (0,0,1,0);
key     = (0,0,0,1);

vardef rgb_to_gray expr c =
    0.2126*redpart c + 0.7152*greenpart c + 0.0722*bluepart c
enddef;

% shorthands
def save_pen       text t = save t; pen       t; enddef;
def save_pair      text t = save t; pair      t; enddef;
def save_path      text t = save t; path      t; enddef;
def save_color     text t = save t; color     t; enddef;
def save_cmykcolor text t = save t; cmykcolor t; enddef;
def save_transform text t = save t; transform t; enddef;
def save_picture   text t = save t; picture   t; enddef;
def save_boolean   text t = save t; boolean   t; enddef;
def save_string    text t = save t; string    t; enddef;

% missing trigonometric functions
vardef tand    primary x = sind(x)/cosd(x) enddef;
vardef arcsind primary x = angle(1+-+x, x) enddef;
vardef arccosd primary x = angle(x, 1+-+x) enddef;
vardef arctand primary x = angle(1, x) enddef;

% segments of the circle (counterclockwise)
vardef arc (expr thetafrom, thetalen) =
    save n, d, l, theta; save_path a; save_pair p, c;
    n = ceiling(thetalen / 45); % number of segments (45° is max segment length)
    d = thetalen / n;           % angle of each segment
    l = 4/3 * tand(d/4);        % length of control points
    theta := thetafrom;
    p := (cosd theta, sind theta);
    c := l * (-sind theta, cosd theta);
    a := p for _ = 1 upto n:
        .. controls (p + c)
        hide(theta := theta + d;
            p := (cosd theta, sind theta);
            c := l * (-sind theta, cosd theta);)
        and (p - c) .. p
    endfor; a enddef;

% some linear algebra
primarydef v extprod w = begingroup
    xpart v * ypart w - ypart v * xpart w
endgroup enddef;

vardef collinear(expr p,q,r) =
    (p <> q) and (q <> r) and (p <> r)
    and (eps > abs( (p-q) extprod (q-r) ))
enddef;

% type helpers
def typeof (expr v) =
    if numeric v: numeric
    elseif pair v: pair
    elseif color v: color
    elseif cmykcolor v: cmykcolor
    elseif boolean v: boolean
    elseif path v: path
    elseif picture v: picture
    elseif transform v: transform
    elseif string v: string
    elseif pen v: pen
    fi enddef;

vardef empty suffix s = save_boolean b;
    b := string _EMPTY_ s; b enddef;
string _EMPTY_;