|
25 | 25 | dofile("plplot_examples.lua") |
26 | 26 |
|
27 | 27 |
|
| 28 | +-------------------------------------------------------------------------- |
| 29 | +-- Calculate greatest common divisor following pseudo-code for the |
| 30 | +-- Euclidian algorithm at http://en.wikipedia.org/wiki/Euclidean_algorithm |
| 31 | + |
| 32 | +function gcd (a, b) |
| 33 | + a = math.floor(math.abs(a)) |
| 34 | + b = math.floor(math.abs(b)) |
| 35 | + while b~=0 do |
| 36 | + t = b |
| 37 | + b = math.mod(a,b) |
| 38 | + a = t |
| 39 | + end |
| 40 | + return a |
| 41 | +end |
| 42 | + |
28 | 43 | function cycloid() |
29 | 44 | -- TODO |
30 | 45 | end |
31 | 46 |
|
32 | 47 |
|
33 | | -function spiro( params ) |
34 | | - NPNT = 20000 |
| 48 | +function spiro( params, fill ) |
| 49 | + NPNT = 2000 |
35 | 50 | xcoord = {} |
36 | 51 | ycoord = {} |
37 | 52 |
|
38 | 53 | -- Fill the coordinates |
39 | | - windings = params[4] |
| 54 | + -- Proper termination of the angle loop very near the beginning |
| 55 | + -- point, see |
| 56 | + -- http://mathforum.org/mathimages/index.php/Hypotrochoid. |
| 57 | + windings = math.floor(math.abs(params[2])/gcd(params[1], params[2])) |
40 | 58 | steps = math.floor(NPNT/windings) |
41 | | - dphi = 8*math.acos(-1)/steps |
42 | | - |
43 | | - xmin = 0 -- This initialisation is safe! |
44 | | - xmax = 0 |
45 | | - ymin = 0 |
46 | | - ymax = 0 |
| 59 | + dphi = 2*math.pi/steps |
47 | 60 |
|
48 | 61 | for i = 1, windings*steps+1 do |
49 | 62 | phi = (i-1) * dphi |
50 | 63 | phiw = (params[1]-params[2])/params[2]*phi |
51 | 64 | xcoord[i] = (params[1]-params[2])*math.cos(phi) + params[3]*math.cos(phiw) |
52 | 65 | ycoord[i] = (params[1]-params[2])*math.sin(phi) - params[3]*math.sin(phiw) |
53 | 66 |
|
| 67 | + if i == 1 then |
| 68 | + xmin = xcoord[i] |
| 69 | + xmax = xcoord[i] |
| 70 | + ymin = ycoord[i] |
| 71 | + ymax = ycoord[i] |
| 72 | + end |
54 | 73 | if xmin>xcoord[i] then xmin = xcoord[i] end |
55 | 74 | if xmax<xcoord[i] then xmax = xcoord[i] end |
56 | 75 | if ymin>ycoord[i] then ymin = ycoord[i] end |
57 | 76 | if ymax<ycoord[i] then ymax = ycoord[i] end |
58 | 77 | end |
59 | 78 |
|
60 | | - if (xmax-xmin)>(ymax-ymin) then |
61 | | - scale = xmax - xmin |
62 | | - else |
63 | | - scale = ymax - ymin |
64 | | - end |
65 | | - xmin = -0.65*scale |
66 | | - xmax = 0.65*scale |
67 | | - ymin = -0.65*scale |
68 | | - ymax = 0.65*scale |
| 79 | + xmin = xmin - 0.15*(xmax-xmin) |
| 80 | + xmax = xmax + 0.15*(xmax-xmin) |
| 81 | + ymin = ymin - 0.15*(ymax-ymin) |
| 82 | + ymax = ymax + 0.15*(ymax-ymin) |
69 | 83 |
|
70 | 84 | pl.wind(xmin, xmax, ymin, ymax) |
71 | 85 |
|
72 | 86 | pl.col0(1) |
73 | | - pl.line(xcoord, ycoord) |
| 87 | + if fill == 1 then |
| 88 | + pl.fill(xcoord, ycoord) |
| 89 | + else |
| 90 | + pl.line(xcoord, ycoord) |
| 91 | + end |
74 | 92 | end |
75 | 93 |
|
76 | 94 |
|
|
83 | 101 | ---------------------------------------------------------------------------- |
84 | 102 |
|
85 | 103 | -- R, r, p, N |
| 104 | +-- R and r should be integers to give correct termination of the |
| 105 | +-- angle loop using gcd. |
| 106 | +-- N.B. N is just a place holder since it is no longer used |
| 107 | +-- (because we now have proper termination of the angle loop). |
| 108 | + |
86 | 109 | params = { |
87 | 110 | { 21, 7, 7, 3 }, -- Deltoid |
88 | 111 | { 21, 7, 10, 3 }, |
@@ -110,20 +133,31 @@ cycloid() |
110 | 133 |
|
111 | 134 | pl.ssub(3, 3) -- Three by three window |
112 | 135 |
|
| 136 | +fill = 0 |
| 137 | +for i = 1, 9 do |
| 138 | + pl.adv(0) |
| 139 | + pl.vpor(0, 1, 0, 1) |
| 140 | + spiro(params[i], fill) |
| 141 | +end |
| 142 | + |
| 143 | +pl.adv(0) |
| 144 | +pl.ssub(1, 1) -- One window per curve |
| 145 | + |
113 | 146 | for i = 1, 9 do |
114 | 147 | pl.adv(0) |
115 | 148 | pl.vpor(0, 1, 0, 1) |
116 | | - spiro(params[i]) |
| 149 | + spiro(params[i], fill) |
117 | 150 | end |
118 | 151 |
|
| 152 | +-- fill the curves. |
| 153 | +fill = 1 |
119 | 154 | pl.adv(0) |
120 | 155 | pl.ssub(1, 1) -- One window per curve |
121 | 156 |
|
122 | 157 | for i = 1, 9 do |
123 | 158 | pl.adv(0) |
124 | 159 | pl.vpor(0, 1, 0, 1) |
125 | | - spiro(params[i]) |
| 160 | + spiro(params[i], fill) |
126 | 161 | end |
127 | 162 |
|
128 | | --- Don't forget to call plend() to finish off! |
129 | 163 | pl.plend() |
0 commit comments