14 * |
14 * |
15 * You should have received a copy of the GNU General Public License |
15 * You should have received a copy of the GNU General Public License |
16 * along with this program. If not, see <http://www.gnu.org/licenses/>. |
16 * along with this program. If not, see <http://www.gnu.org/licenses/>. |
17 */ |
17 */ |
18 |
18 |
19 #ifndef MISC_H |
19 #ifndef LDFORGE_MISC_H |
20 #define MISC_H |
20 #define LDFORGE_MISC_H |
21 |
21 |
22 #include <QVector> |
22 #include <QVector> |
23 #include "config.h" |
23 #include "config.h" |
24 #include "common.h" |
24 #include "main.h" |
25 #include "types.h" |
25 #include "types.h" |
26 |
26 |
27 #define NUM_PRIMES 500 |
27 #define NUM_PRIMES 500 |
28 |
28 |
|
29 class LDDocument; |
29 class QColor; |
30 class QColor; |
30 class QAction; |
31 class QAction; |
31 |
32 |
32 // Prime numbers |
33 // Prime numbers |
33 extern const int g_primes[NUM_PRIMES]; |
34 extern const int g_primes[NUM_PRIMES]; |
34 |
35 |
35 // Returns whether a given string represents a floating point number. |
36 // Returns whether a given string represents a floating point number. |
36 bool numeric (const str& tok); |
37 bool numeric (const QString& tok); |
37 |
38 |
38 // Simplifies the given fraction. |
39 // Simplifies the given fraction. |
39 void simplify (int& numer, int& denom); |
40 void simplify (int& numer, int& denom); |
40 |
41 |
41 str join (initlist<StringFormatArg> vals, str delim = " "); |
42 void roundToDecimals (double& a, int decimals); |
|
43 |
|
44 QString join (initlist<StringFormatArg> vals, QString delim = " "); |
42 |
45 |
43 // Grid stuff |
46 // Grid stuff |
44 struct gridinfo |
47 struct gridinfo |
45 { const char* const name; |
48 { |
46 FloatConfig* const confs[4]; |
49 const char* const name; |
|
50 float* const confs[4]; |
47 }; |
51 }; |
48 |
52 |
49 extern_cfg (Int, grid); |
53 extern_cfg (Int, grid); |
50 static const int g_NumGrids = 3; |
54 static const int g_NumGrids = 3; |
51 extern const gridinfo g_GridInfo[3]; |
55 extern const gridinfo g_GridInfo[3]; |
52 |
56 |
53 inline const gridinfo& currentGrid() |
57 inline const gridinfo& currentGrid() |
54 { return g_GridInfo[grid]; |
58 { |
|
59 return g_GridInfo[grid]; |
55 } |
60 } |
56 |
61 |
57 // ============================================================================= |
62 // ============================================================================= |
58 enum RotationPoint |
63 enum ERotationPoint |
59 { ObjectOrigin, |
64 { |
60 WorldOrigin, |
65 EObjectOrigin, |
61 CustomPoint |
66 EWorldOrigin, |
|
67 ECustomPoint |
62 }; |
68 }; |
63 |
69 |
64 vertex rotPoint (const QList<LDObject*>& objs); |
70 Vertex rotPoint (const LDObjectList& objs); |
65 void configRotationPoint(); |
71 void configRotationPoint(); |
66 |
72 |
67 // ============================================================================= |
73 // ============================================================================= |
68 namespace Grid |
74 namespace Grid |
69 { enum Type |
75 { |
70 { Coarse, |
76 enum Type |
|
77 { |
|
78 Coarse, |
71 Medium, |
79 Medium, |
72 Fine |
80 Fine |
73 }; |
81 }; |
74 |
82 |
75 enum Config |
83 enum Config |
76 { X, |
84 { |
|
85 X, |
77 Y, |
86 Y, |
78 Z, |
87 Z, |
79 Angle |
88 Angle |
80 }; |
89 }; |
81 |
90 |
82 double snap (double value, const Grid::Config axis); |
91 double snap (double value, const Grid::Config axis); |
83 } |
92 } |
84 |
93 |
85 // ============================================================================= |
|
86 // RingFinder |
|
87 // |
|
88 // Provides an algorithm for finding a solution of rings between radii r0 and r1. |
|
89 // ============================================================================= |
|
90 class RingFinder |
|
91 { public: |
|
92 struct Component |
|
93 { int num; |
|
94 double scale; |
|
95 }; |
|
96 |
|
97 class Solution |
|
98 { public: |
|
99 // Components of this solution |
|
100 inline const QVector<Component>& components() const |
|
101 { return m_components; |
|
102 } |
|
103 |
|
104 // Add a component to this solution |
|
105 void addComponent (const Component& a) |
|
106 { m_components.push_back (a); |
|
107 } |
|
108 |
|
109 // Compare solutions |
|
110 bool operator> (const Solution& other) const; |
|
111 |
|
112 private: |
|
113 QVector<Component> m_components; |
|
114 }; |
|
115 |
|
116 RingFinder() {} |
|
117 bool findRings (double r0, double r1); |
|
118 |
|
119 inline const Solution* bestSolution() |
|
120 { return m_bestSolution; |
|
121 } |
|
122 |
|
123 inline const QVector<Solution>& allSolutions() const |
|
124 { return m_solutions; |
|
125 } |
|
126 |
|
127 inline bool operator() (double r0, double r1) |
|
128 { return findRings (r0, r1); |
|
129 } |
|
130 |
|
131 private: |
|
132 QVector<Solution> m_solutions; |
|
133 const Solution* m_bestSolution; |
|
134 int m_stack; |
|
135 |
|
136 bool findRingsRecursor (double r0, double r1, Solution& currentSolution); |
|
137 }; |
|
138 |
|
139 extern RingFinder g_RingFinder; |
|
140 |
|
141 // ============================================================================= |
|
142 template<class T> void dataswap (T& a, T& b) |
|
143 { T c = a; |
|
144 a = b; |
|
145 b = c; |
|
146 } |
|
147 |
|
148 // ----------------------------------------------------------------------------- |
94 // ----------------------------------------------------------------------------- |
149 // Plural expression |
95 // Plural expression |
150 template<class T> static inline const char* plural (T n) |
96 template<class T> static inline const char* plural (T n) |
151 { return (n != 1) ? "s" : ""; |
97 { |
|
98 return (n != 1) ? "s" : ""; |
152 } |
99 } |
153 |
100 |
154 // ----------------------------------------------------------------------------- |
101 // ----------------------------------------------------------------------------- |
155 // Templated clamp |
102 // Templated clamp |
156 template<class T> static inline T clamp (T a, T min, T max) |
103 template<class T> static inline T clamp (T a, T min, T max) |
157 { return (a > max) ? max : (a < min) ? min : a; |
104 { |
|
105 return (a > max) ? max : (a < min) ? min : a; |
158 } |
106 } |
159 |
107 |
160 // Templated minimum |
108 // Templated minimum |
161 template<class T> static inline T min (T a, T b) |
109 template<class T> static inline T min (T a, T b) |
162 { return (a < b) ? a : b; |
110 { |
|
111 return (a < b) ? a : b; |
163 } |
112 } |
164 |
113 |
165 // Templated maximum |
114 // Templated maximum |
166 template<class T> static inline T max (T a, T b) |
115 template<class T> static inline T max (T a, T b) |
167 { return (a > b) ? a : b; |
116 { |
|
117 return (a > b) ? a : b; |
168 } |
118 } |
169 |
119 |
170 // Templated absolute value |
120 // Templated absolute value |
171 template<class T> static inline T abs (T a) |
121 template<class T> static inline T abs (T a) |
172 { return (a >= 0) ? a : -a; |
122 { |
|
123 return (a >= 0) ? a : -a; |
173 } |
124 } |
174 |
125 |
175 template<class T> inline bool isZero (T a) |
126 template<class T> inline bool isZero (T a) |
176 { return abs<T> (a) < 0.0001; |
127 { |
|
128 return abs<T> (a) < 0.0001; |
177 } |
129 } |
178 |
130 |
179 template<class T> inline bool isInteger (T a) |
131 template<class T> inline bool isInteger (T a) |
180 { return isZero (a - (int) a); |
132 { |
|
133 return isZero (a - (int) a); |
181 } |
134 } |
182 |
135 |
183 template<class T> void removeDuplicates (QList<T>& a) |
136 template<class T> void removeDuplicates (QList<T>& a) |
184 { std::sort (a.begin(), a.end()); |
137 { |
185 typename QList<T>::iterator pos = std::unique (a.begin(), a.end()); |
138 std::sort (a.begin(), a.end()); |
186 a.erase (pos, a.end()); |
139 a.erase (std::unique (a.begin(), a.end()), a.end()); |
187 } |
140 } |
188 |
141 |
189 #endif // MISC_H |
142 #endif // LDFORGE_MISC_H |