src/misc/RingFinder.h

Wed, 05 Mar 2014 18:31:22 +0200

author
Santeri Piippo <crimsondusk64@gmail.com>
date
Wed, 05 Mar 2014 18:31:22 +0200
changeset 650
db7146a87ae4
parent 647
b87941923eb4
permissions
-rw-r--r--

- changed doxygen entity style from @argh to \argh

629
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
1 /*
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
2 * LDForge: LDraw parts authoring CAD
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
3 * Copyright (C) 2013, 2014 Santeri Piippo
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
4 *
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
5 * This program is free software: you can redistribute it and/or modify
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
6 * it under the terms of the GNU General Public License as published by
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
7 * the Free Software Foundation, either version 3 of the License, or
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
8 * (at your option) any later version.
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
9 *
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
10 * This program is distributed in the hope that it will be useful,
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
13 * GNU General Public License for more details.
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
14 *
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
17 */
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
18
641
425b169a82aa - changed header guards into #pragma once
Santeri Piippo <crimsondusk64@gmail.com>
parents: 629
diff changeset
19 #pragma once
629
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
20
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
21 #include "../Main.h"
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
22
647
b87941923eb4 - made MessageLog.h and RingFinder.h suitable for doxygen
Santeri Piippo <crimsondusk64@gmail.com>
parents: 641
diff changeset
23 //!
650
db7146a87ae4 - changed doxygen entity style from @argh to \argh
Santeri Piippo <crimsondusk64@gmail.com>
parents: 647
diff changeset
24 //! \brief Provides an algorithm for finding solutions of rings between given radii.
647
b87941923eb4 - made MessageLog.h and RingFinder.h suitable for doxygen
Santeri Piippo <crimsondusk64@gmail.com>
parents: 641
diff changeset
25 //!
b87941923eb4 - made MessageLog.h and RingFinder.h suitable for doxygen
Santeri Piippo <crimsondusk64@gmail.com>
parents: 641
diff changeset
26 //! The RingFinder is a class which implements a ring finding algorithm. It is passed
b87941923eb4 - made MessageLog.h and RingFinder.h suitable for doxygen
Santeri Piippo <crimsondusk64@gmail.com>
parents: 641
diff changeset
27 //! two radii and it tries to find solutions of rings that would fill the given space.
b87941923eb4 - made MessageLog.h and RingFinder.h suitable for doxygen
Santeri Piippo <crimsondusk64@gmail.com>
parents: 641
diff changeset
28 //!
650
db7146a87ae4 - changed doxygen entity style from @argh to \argh
Santeri Piippo <crimsondusk64@gmail.com>
parents: 647
diff changeset
29 //! \note It is not fool-proof and does not always yield a solution, never assume
db7146a87ae4 - changed doxygen entity style from @argh to \argh
Santeri Piippo <crimsondusk64@gmail.com>
parents: 647
diff changeset
30 //! \note that one is a available as none is guaranteed.
647
b87941923eb4 - made MessageLog.h and RingFinder.h suitable for doxygen
Santeri Piippo <crimsondusk64@gmail.com>
parents: 641
diff changeset
31 //!
629
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
32 class RingFinder
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
33 {
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
34 public:
647
b87941923eb4 - made MessageLog.h and RingFinder.h suitable for doxygen
Santeri Piippo <crimsondusk64@gmail.com>
parents: 641
diff changeset
35 //! A single component in a solution
629
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
36 struct Component
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
37 {
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
38 int num;
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
39 double scale;
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
40 };
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
41
647
b87941923eb4 - made MessageLog.h and RingFinder.h suitable for doxygen
Santeri Piippo <crimsondusk64@gmail.com>
parents: 641
diff changeset
42 //! A solution whose components would fill the desired ring space.
629
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
43 class Solution
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
44 {
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
45 public:
650
db7146a87ae4 - changed doxygen entity style from @argh to \argh
Santeri Piippo <crimsondusk64@gmail.com>
parents: 647
diff changeset
46 //! \returns components of this solution
629
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
47 inline const QVector<Component>& getComponents() const
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
48 {
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
49 return m_components;
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
50 }
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
51
647
b87941923eb4 - made MessageLog.h and RingFinder.h suitable for doxygen
Santeri Piippo <crimsondusk64@gmail.com>
parents: 641
diff changeset
52 //! Add a component to this solution
629
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
53 inline void addComponent (const Component& a)
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
54 {
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
55 m_components.push_back (a);
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
56 }
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
57
650
db7146a87ae4 - changed doxygen entity style from @argh to \argh
Santeri Piippo <crimsondusk64@gmail.com>
parents: 647
diff changeset
58 //! \brief Compare solutions.
647
b87941923eb4 - made MessageLog.h and RingFinder.h suitable for doxygen
Santeri Piippo <crimsondusk64@gmail.com>
parents: 641
diff changeset
59 //!
650
db7146a87ae4 - changed doxygen entity style from @argh to \argh
Santeri Piippo <crimsondusk64@gmail.com>
parents: 647
diff changeset
60 //! Compares this solution with \c other and determines which
647
b87941923eb4 - made MessageLog.h and RingFinder.h suitable for doxygen
Santeri Piippo <crimsondusk64@gmail.com>
parents: 641
diff changeset
61 //! one is superior.
b87941923eb4 - made MessageLog.h and RingFinder.h suitable for doxygen
Santeri Piippo <crimsondusk64@gmail.com>
parents: 641
diff changeset
62 //!
b87941923eb4 - made MessageLog.h and RingFinder.h suitable for doxygen
Santeri Piippo <crimsondusk64@gmail.com>
parents: 641
diff changeset
63 //! A solution is considered superior if solution has less
b87941923eb4 - made MessageLog.h and RingFinder.h suitable for doxygen
Santeri Piippo <crimsondusk64@gmail.com>
parents: 641
diff changeset
64 //! components than the other one. If both solution have an
b87941923eb4 - made MessageLog.h and RingFinder.h suitable for doxygen
Santeri Piippo <crimsondusk64@gmail.com>
parents: 641
diff changeset
65 //! equal amount components, the solution with a lesser maximum
b87941923eb4 - made MessageLog.h and RingFinder.h suitable for doxygen
Santeri Piippo <crimsondusk64@gmail.com>
parents: 641
diff changeset
66 //! ring number is found superior, as such solutions should
b87941923eb4 - made MessageLog.h and RingFinder.h suitable for doxygen
Santeri Piippo <crimsondusk64@gmail.com>
parents: 641
diff changeset
67 //! yield less new primitives and cleaner definitions.
b87941923eb4 - made MessageLog.h and RingFinder.h suitable for doxygen
Santeri Piippo <crimsondusk64@gmail.com>
parents: 641
diff changeset
68 //!
b87941923eb4 - made MessageLog.h and RingFinder.h suitable for doxygen
Santeri Piippo <crimsondusk64@gmail.com>
parents: 641
diff changeset
69 //! The solution which is found superior to every other solution
650
db7146a87ae4 - changed doxygen entity style from @argh to \argh
Santeri Piippo <crimsondusk64@gmail.com>
parents: 647
diff changeset
70 //! will be the one returned by \c RingFinder::bestSolution().
647
b87941923eb4 - made MessageLog.h and RingFinder.h suitable for doxygen
Santeri Piippo <crimsondusk64@gmail.com>
parents: 641
diff changeset
71 //!
650
db7146a87ae4 - changed doxygen entity style from @argh to \argh
Santeri Piippo <crimsondusk64@gmail.com>
parents: 647
diff changeset
72 //! \param other the solution to check against
db7146a87ae4 - changed doxygen entity style from @argh to \argh
Santeri Piippo <crimsondusk64@gmail.com>
parents: 647
diff changeset
73 //! \returns whether this solution is considered superior
db7146a87ae4 - changed doxygen entity style from @argh to \argh
Santeri Piippo <crimsondusk64@gmail.com>
parents: 647
diff changeset
74 //! \returns to \c other.
647
b87941923eb4 - made MessageLog.h and RingFinder.h suitable for doxygen
Santeri Piippo <crimsondusk64@gmail.com>
parents: 641
diff changeset
75 //!
b87941923eb4 - made MessageLog.h and RingFinder.h suitable for doxygen
Santeri Piippo <crimsondusk64@gmail.com>
parents: 641
diff changeset
76 bool isSuperiorTo (const Solution* other) const;
629
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
77
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
78 private:
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
79 QVector<Component> m_components;
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
80 };
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
81
647
b87941923eb4 - made MessageLog.h and RingFinder.h suitable for doxygen
Santeri Piippo <crimsondusk64@gmail.com>
parents: 641
diff changeset
82 //! Constructs a ring finder.
629
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
83 RingFinder() {}
647
b87941923eb4 - made MessageLog.h and RingFinder.h suitable for doxygen
Santeri Piippo <crimsondusk64@gmail.com>
parents: 641
diff changeset
84
650
db7146a87ae4 - changed doxygen entity style from @argh to \argh
Santeri Piippo <crimsondusk64@gmail.com>
parents: 647
diff changeset
85 //! \brief Tries to find rings between \c r0 and \c r1.
647
b87941923eb4 - made MessageLog.h and RingFinder.h suitable for doxygen
Santeri Piippo <crimsondusk64@gmail.com>
parents: 641
diff changeset
86 //!
b87941923eb4 - made MessageLog.h and RingFinder.h suitable for doxygen
Santeri Piippo <crimsondusk64@gmail.com>
parents: 641
diff changeset
87 //! This is the main algorithm of the ring finder. It tries to use math
b87941923eb4 - made MessageLog.h and RingFinder.h suitable for doxygen
Santeri Piippo <crimsondusk64@gmail.com>
parents: 641
diff changeset
88 //! to find the one ring between r0 and r1. If it fails (the ring number
b87941923eb4 - made MessageLog.h and RingFinder.h suitable for doxygen
Santeri Piippo <crimsondusk64@gmail.com>
parents: 641
diff changeset
89 //! is non-integral), it finds an intermediate radius (ceil of the ring
b87941923eb4 - made MessageLog.h and RingFinder.h suitable for doxygen
Santeri Piippo <crimsondusk64@gmail.com>
parents: 641
diff changeset
90 //! number times scale) and splits the radius at this point, calling this
b87941923eb4 - made MessageLog.h and RingFinder.h suitable for doxygen
Santeri Piippo <crimsondusk64@gmail.com>
parents: 641
diff changeset
91 //! function again to try find the rings between r0 - r and r - r1.
b87941923eb4 - made MessageLog.h and RingFinder.h suitable for doxygen
Santeri Piippo <crimsondusk64@gmail.com>
parents: 641
diff changeset
92 //!
b87941923eb4 - made MessageLog.h and RingFinder.h suitable for doxygen
Santeri Piippo <crimsondusk64@gmail.com>
parents: 641
diff changeset
93 //! This does not always yield into usable results. If at some point r ==
b87941923eb4 - made MessageLog.h and RingFinder.h suitable for doxygen
Santeri Piippo <crimsondusk64@gmail.com>
parents: 641
diff changeset
94 //! r0 or r == r1, there is no hope of finding the rings, at least with
b87941923eb4 - made MessageLog.h and RingFinder.h suitable for doxygen
Santeri Piippo <crimsondusk64@gmail.com>
parents: 641
diff changeset
95 //! this algorithm, as it would fall into an infinite recursion.
b87941923eb4 - made MessageLog.h and RingFinder.h suitable for doxygen
Santeri Piippo <crimsondusk64@gmail.com>
parents: 641
diff changeset
96 //!
650
db7146a87ae4 - changed doxygen entity style from @argh to \argh
Santeri Piippo <crimsondusk64@gmail.com>
parents: 647
diff changeset
97 //! \param r0 the lower radius of the ring space
db7146a87ae4 - changed doxygen entity style from @argh to \argh
Santeri Piippo <crimsondusk64@gmail.com>
parents: 647
diff changeset
98 //! \param r1 the higher radius of the ring space
db7146a87ae4 - changed doxygen entity style from @argh to \argh
Santeri Piippo <crimsondusk64@gmail.com>
parents: 647
diff changeset
99 //! \returns whether it was possible to find a solution for the given
db7146a87ae4 - changed doxygen entity style from @argh to \argh
Santeri Piippo <crimsondusk64@gmail.com>
parents: 647
diff changeset
100 //! \returns ring space.
647
b87941923eb4 - made MessageLog.h and RingFinder.h suitable for doxygen
Santeri Piippo <crimsondusk64@gmail.com>
parents: 641
diff changeset
101 //!
629
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
102 bool findRings (double r0, double r1);
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
103
650
db7146a87ae4 - changed doxygen entity style from @argh to \argh
Santeri Piippo <crimsondusk64@gmail.com>
parents: 647
diff changeset
104 //! \returns the solution that was considered best. Returns \c null
db7146a87ae4 - changed doxygen entity style from @argh to \argh
Santeri Piippo <crimsondusk64@gmail.com>
parents: 647
diff changeset
105 //! \returns if no suitable solution was found.
db7146a87ae4 - changed doxygen entity style from @argh to \argh
Santeri Piippo <crimsondusk64@gmail.com>
parents: 647
diff changeset
106 //! \see \c RingFinder::Solution::isSuperiorTo()
629
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
107 inline const Solution* bestSolution()
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
108 {
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
109 return m_bestSolution;
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
110 }
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
111
650
db7146a87ae4 - changed doxygen entity style from @argh to \argh
Santeri Piippo <crimsondusk64@gmail.com>
parents: 647
diff changeset
112 //! \returns all found solutions. The list is empty if no solutions
db7146a87ae4 - changed doxygen entity style from @argh to \argh
Santeri Piippo <crimsondusk64@gmail.com>
parents: 647
diff changeset
113 //! \returns were found.
629
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
114 inline const QVector<Solution>& allSolutions() const
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
115 {
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
116 return m_solutions;
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
117 }
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
118
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
119 private:
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
120 QVector<Solution> m_solutions;
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
121 const Solution* m_bestSolution;
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
122 int m_stack;
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
123
650
db7146a87ae4 - changed doxygen entity style from @argh to \argh
Santeri Piippo <crimsondusk64@gmail.com>
parents: 647
diff changeset
124 //! Helper function for \c findRings
629
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
125 bool findRingsRecursor (double r0, double r1, Solution& currentSolution);
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
126 };
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
127
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
128 extern RingFinder g_RingFinder;
b75c6cce02e2 - refactored filenames
Santeri Piippo <crimsondusk64@gmail.com>
parents:
diff changeset
129

mercurial