wrestlers.tex: Let `\section' act as a section header in the source.
[doc/wrestlers] / ecc.mp
1 %% Elliptic curve messing about
2
3 %% y^2 = x^3 + a x^2 + b
4
5 numeric u, v;
6 numeric a, b;
7 numeric minx, maxx, miny, maxy;
8 transform gt;
9 pair O;
10 %% prologues := 1;
11 a = -2; b = 1;
12 scale = 2 cm;
13 labeloffset := 6 pt;
14
15 ahlength := 2 mm;
16 ahangle := 30;
17
18 O = (0, 0);
19
20 vardef ecy(expr x) = sqrt (x*x*x + a*x + b) enddef;
21 vardef ecadd(expr u, v) =
22 numeric ux, uy, vx, vy;
23 numeric dx, dy;
24 numeric m;
25 ux := xpart u; uy = ypart u;
26 vx := xpart v; vy = ypart v;
27 if ux = vx:
28 m := (3*ux*ux + a)/(2*uy);
29 else:
30 m := (vy - uy)/(vx - ux);
31 fi
32 dx := m**2 - ux - vx;
33 dy := m * (ux - dx) - uy;
34 (dx, dy)
35 enddef;
36
37 minx = -2; maxx = 3;
38 maxy = ecy(maxx); miny = -maxy;
39 u = 7/5 cm;
40 v = u * (maxx - minx)/(maxy - miny);
41 gt = identity xscaled u yscaled v shifted (10 cm, 10 cm);
42
43 vardef eclabel@#(expr l, z) =
44 pickup pencircle scaled 1/4 pt;
45 draw fullcircle scaled 1 mm shifted (z transformed gt);
46 draw thelabel@#(l, z transformed gt);
47 enddef;
48
49 vardef drawcurve =
50 boolean ok;
51 path p;
52 numeric t;
53 pickup pencircle scaled 1/4 pt;
54 drawarrow ((minx, 0) -- (maxx, 0)) transformed gt;
55 drawarrow ((0, miny) -- (0, maxy)) transformed gt;
56 ok := false;
57 pickup pencircle scaled 2/3 pt;
58 for x = minx step 0.01 until maxx:
59 t := x*x*x + a*x + b;
60 if t >= 0:
61 y := sqrt t;
62 if ok:
63 p := p .. (x, y);
64 else:
65 p := (x, y);
66 fi
67 ok := true;
68 else:
69 if ok:
70 draw (reverse p reflectedabout (O, O + right) .. p .. cycle)
71 transformed gt;
72 fi
73 ok := false;
74 fi
75 endfor
76 if ok:
77 draw (reverse p reflectedabout (O, O + right) .. p) transformed gt;
78 fi
79 enddef;
80
81 vardef setbackground(expr c) =
82 save bboxmargin;
83 picture pic;
84 bboxmargin := 1/2 cm;
85 pic := currentpicture;
86 currentpicture := nullpicture;
87 fill (bbox pic) withcolor c;
88 draw pic;
89 enddef;
90
91 beginfig(0);
92 drawcurve;
93 x0 := -5/4; x1 := 1/4;
94 y0 := -ecy(x0); y1 := ecy(x1);
95 z2 = ecadd(z0, z1);
96 x3 := x2; y3 := -y2;
97 pickup pencircle scaled 1/4 pt;
98 draw ((-0.1)[z0, z3] -- 1.1[z0, z3]) transformed gt dashed evenly;
99 draw ((-0.1)[z2, z3] -- 1.1[z2, z3]) transformed gt dashed evenly;
100 eclabel.bot(btex $P_0$ etex, z0);
101 eclabel.top(btex $P_1$ etex, z1);
102 eclabel.rt(btex $P'$ etex, z3);
103 eclabel.lft(btex $P_2 = -P' = P_0 + P_1$ etex, z2);
104 setbackground(white);
105 endfig;
106
107 beginfig(1);
108 drawcurve;
109 x0 := -18/16;
110 y0 = ecy(x0);
111 z1 = ecadd(z0, z0);
112 x2 := x1; y2 := -y1;
113 pickup pencircle scaled 1/4 pt;
114 draw ((-0.1)[z0, z2] -- 1.1[z0, z2]) transformed gt dashed evenly;
115 draw ((-0.1)[z2, z1] -- 1.1[z2, z1]) transformed gt dashed evenly;
116 eclabel.top(btex $P_0$ etex, z0);
117 eclabel.rt(btex $P'$ etex, z2);
118 eclabel.lft(btex $P_1 = -P' = 2 P_0$ etex, z1);
119 setbackground(white);
120 endfig;
121
122 beginfig(2);
123 drawcurve;
124 x0 := 5/2;
125 y0 = ecy(x0);
126 x1 := x0; y1 := -y0;
127 pickup pencircle scaled 1/4 pt;
128 draw ((x0, miny) -- (x0, maxy)) transformed gt dashed evenly;
129 eclabel.rt(btex $P_0$ etex, z0);
130 eclabel.rt(btex $P_1$ etex, z1);
131 setbackground(white);
132 endfig;
133
134 end;