src/misc.cpp

changeset 500
cad8cdc42a64
parent 498
791c831c8020
child 501
8f314f3f5054
equal deleted inserted replaced
499:ebd30d9eb667 500:cad8cdc42a64
22 #include "common.h" 22 #include "common.h"
23 #include "misc.h" 23 #include "misc.h"
24 #include "gui.h" 24 #include "gui.h"
25 #include "dialogs.h" 25 #include "dialogs.h"
26 #include "ui_rotpoint.h" 26 #include "ui_rotpoint.h"
27
28 RingFinder g_RingFinder;
27 29
28 // Prime number table. 30 // Prime number table.
29 const int g_primes[NUM_PRIMES] = 31 const int g_primes[NUM_PRIMES] =
30 { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 32 { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29,
31 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 33 31, 37, 41, 43, 47, 53, 59, 61, 67, 71,
179 return true; 181 return true;
180 } 182 }
181 183
182 // ============================================================================= 184 // =============================================================================
183 // ----------------------------------------------------------------------------- 185 // -----------------------------------------------------------------------------
184 void simplify (short& numer, short& denom) 186 void simplify (int& numer, int& denom)
185 { bool repeat; 187 { bool repeat;
186 188
187 do 189 do
188 { repeat = false; 190 { repeat = false;
189 191
272 // ============================================================================= 274 // =============================================================================
273 // ----------------------------------------------------------------------------- 275 // -----------------------------------------------------------------------------
274 str join (initlist<StringFormatArg> vals, str delim) 276 str join (initlist<StringFormatArg> vals, str delim)
275 { QStringList list; 277 { QStringList list;
276 278
277 for (const StringFormatArg & arg : vals) 279 for (const StringFormatArg& arg : vals)
278 list << arg.value(); 280 list << arg.value();
279 281
280 return list.join (delim); 282 return list.join (delim);
281 } 283 }
282 284
299 301
300 double fval = atof (buf); 302 double fval = atof (buf);
301 delete[] buf; 303 delete[] buf;
302 return fval; 304 return fval;
303 } 305 }
306
307 // =============================================================================
308 // This is the main algorithm of the ring finder. It tries to use math to find
309 // the one ring between r0 and r1. If it fails (the ring number is non-integral),
310 // it finds an intermediate radius (ceil of the ring number times scale) and
311 // splits the radius at this point, calling this function again to try find the
312 // rings between r0 - r and r - r1.
313 //
314 // This does not always yield into usable results. If at some point r == r0 or
315 // r == r1, there is no hope of finding the rings, at least with this algorithm,
316 // as it would fall into an infinite recursion.
317 // -----------------------------------------------------------------------------
318 bool RingFinder::findRings (double r0, double r1)
319 { // Find the scale and number of a ring between r1 and r0.
320 double scale = r1 - r0;
321 double num = r0 / scale;
322
323 // If the ring number is integral, we have found a fitting ring to r0 -> r1!
324 if (isInteger (num))
325 { SolutionComponent cmp;
326 cmp.scale = scale;
327 cmp.num = (int) ceil (num);
328 m_solution << cmp;
329 }
330 else
331 { // If not, find an intermediate <r> between the radii
332 double r = ceil (num) * scale;
333
334 // If r is the same as r0 or r1, we simply cannot find any rings between
335 // r0 and r1. Stop and return failure.
336 if (isZero (r0 - r) || isZero (r1 - r))
337 return false;
338
339 // Split this ring into r0 -> r and r -> r1. Recurse to possibly find
340 // the rings for these. If either recurse fails, the entire algorithm
341 // fails as well.
342 if (!findRings (r0, r) || !findRings (r, r1))
343 return false;
344 }
345
346 // The algorithm did not fail, thus we succeeded!
347 return true;
348 }

mercurial