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, |
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 } |