Commit | Line | Data |
---|---|---|
a6e375a6 MW |
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; |