FreeCAD

Форк
0
/
UnitsSchemaImperial1.cpp 
404 строки · 15.1 Кб
1
/***************************************************************************
2
 *   Copyright (c) 2009 Jürgen Riegel <FreeCAD@juergen-riegel.net>         *
3
 *                                                                         *
4
 *   This file is part of the FreeCAD CAx development system.              *
5
 *                                                                         *
6
 *   This library is free software; you can redistribute it and/or         *
7
 *   modify it under the terms of the GNU Library General Public           *
8
 *   License as published by the Free Software Foundation; either          *
9
 *   version 2 of the License, or (at your option) any later version.      *
10
 *                                                                         *
11
 *   This library  is distributed in the hope that it will be useful,      *
12
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
13
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
14
 *   GNU Library General Public License for more details.                  *
15
 *                                                                         *
16
 *   You should have received a copy of the GNU Library General Public     *
17
 *   License along with this library; see the file COPYING.LIB. If not,    *
18
 *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
19
 *   Suite 330, Boston, MA  02111-1307, USA                                *
20
 *                                                                         *
21
 ***************************************************************************/
22

23

24
#include "PreCompiled.h"
25
#ifndef _PreComp_
26
#include <cmath>
27
#include <sstream>
28
#endif
29
#ifdef __GNUC__
30
#include <unistd.h>
31
#endif
32

33
#include <QString>
34

35
#include "UnitsSchemaImperial1.h"
36

37

38
using namespace Base;
39

40

41
QString
42
UnitsSchemaImperial1::schemaTranslate(const Quantity& quant, double& factor, QString& unitString)
43
{
44
    double UnitValue = std::abs(quant.getValue());
45
    Unit unit = quant.getUnit();
46
    // for imperial user/programmer mind; UnitValue is in internal system, that means
47
    // mm/kg/s. And all combined units have to be calculated from there!
48

49
    // now do special treatment on all cases seems necessary:
50
    if (unit == Unit::Length) {        // Length handling ============================
51
        if (UnitValue < 0.00000254) {  // smaller then 0.001 thou -> inch and scientific notation
52
            unitString = QString::fromLatin1("in");
53
            factor = 25.4;
54
        }
55
        else if (UnitValue < 2.54) {  // smaller then 0.1 inch -> Thou (mil)
56
            unitString = QString::fromLatin1("thou");
57
            factor = 0.0254;
58
        }
59
        else if (UnitValue < 304.8) {
60
            unitString = QString::fromLatin1("\"");
61
            factor = 25.4;
62
        }
63
        else if (UnitValue < 914.4) {
64
            unitString = QString::fromLatin1("\'");
65
            factor = 304.8;
66
        }
67
        else if (UnitValue < 1609344.0) {
68
            unitString = QString::fromLatin1("yd");
69
            factor = 914.4;
70
        }
71
        else if (UnitValue < 1609344000.0) {
72
            unitString = QString::fromLatin1("mi");
73
            factor = 1609344.0;
74
        }
75
        else {  // bigger then 1000 mi -> scientific notation
76
            unitString = QString::fromLatin1("in");
77
            factor = 25.4;
78
        }
79
    }
80
    else if (unit == Unit::Angle) {
81
        unitString = QString::fromUtf8("\xC2\xB0");
82
        factor = 1.0;
83
    }
84
    else if (unit == Unit::Area) {
85
        // TODO: Cascade for the Areas
86
        // default action for all cases without special treatment:
87
        unitString = QString::fromLatin1("in^2");
88
        factor = 645.16;
89
    }
90
    else if (unit == Unit::Volume) {
91
        // TODO: Cascade for the Volume
92
        // default action for all cases without special treatment:
93
        unitString = QString::fromLatin1("in^3");
94
        factor = 16387.064;
95
    }
96
    else if (unit == Unit::Mass) {
97
        // TODO: Cascade for the weights
98
        // default action for all cases without special treatment:
99
        unitString = QString::fromLatin1("lb");
100
        factor = 0.45359237;
101
    }
102
    else if (unit == Unit::Pressure) {
103
        if (UnitValue < 6894.744) {  // psi is the smallest
104
            unitString = QString::fromLatin1("psi");
105
            factor = 6.894744825494;
106
        }
107
        else if (UnitValue < 6894744.825) {
108
            unitString = QString::fromLatin1("ksi");
109
            factor = 6894.744825494;
110
        }
111
        else {  // bigger then 1000 ksi -> psi + scientific notation
112
            unitString = QString::fromLatin1("psi");
113
            factor = 6.894744825494;
114
        }
115
    }
116
    else if (unit == Unit::Stiffness) {  // Conversion to lbf/in
117
        unitString = QString::fromLatin1("lbf/in");
118
        factor = 4.448222 / 0.0254;
119
    }
120
    else if (unit == Unit::Velocity) {
121
        unitString = QString::fromLatin1("in/min");
122
        factor = 25.4 / 60;
123
    }
124
    else {
125
        // default action for all cases without special treatment:
126
        unitString = quant.getUnit().getString();
127
        factor = 1.0;
128
    }
129

130
    return toLocale(quant, factor, unitString);
131
}
132

133
QString UnitsSchemaImperialDecimal::schemaTranslate(const Base::Quantity& quant,
134
                                                    double& factor,
135
                                                    QString& unitString)
136
{
137
    // double UnitValue = std::abs(quant.getValue());
138
    Unit unit = quant.getUnit();
139
    // for imperial user/programmer mind; UnitValue is in internal system, that means
140
    // mm/kg/s. And all combined units have to be calculated from there!
141

142
    // now do special treatment on all cases seems necessary:
143
    if (unit == Unit::Length) {  // Length handling ============================
144
        unitString = QString::fromLatin1("in");
145
        factor = 25.4;
146
    }
147
    else if (unit == Unit::Angle) {
148
        unitString = QString::fromUtf8("\xC2\xB0");
149
        factor = 1.0;
150
    }
151
    else if (unit == Unit::Area) {
152
        // TODO: Cascade for the Areas
153
        // default action for all cases without special treatment:
154
        unitString = QString::fromLatin1("in^2");
155
        factor = 645.16;
156
    }
157
    else if (unit == Unit::Volume) {
158
        // TODO: Cascade for the Volume
159
        // default action for all cases without special treatment:
160
        unitString = QString::fromLatin1("in^3");
161
        factor = 16387.064;
162
    }
163
    else if (unit == Unit::Mass) {
164
        // TODO: Cascade for the weights
165
        // default action for all cases without special treatment:
166
        unitString = QString::fromLatin1("lb");
167
        factor = 0.45359237;
168
    }
169
    else if (unit == Unit::Pressure) {
170
        unitString = QString::fromLatin1("psi");
171
        factor = 6.894744825494;
172
    }
173
    else if (unit == Unit::Stiffness) {
174
        unitString = QString::fromLatin1("lbf/in");
175
        factor = 4.448222 / 0.0254;
176
    }
177
    else if (unit == Unit::Velocity) {
178
        unitString = QString::fromLatin1("in/min");
179
        factor = 25.4 / 60;
180
    }
181
    else if (unit == Unit::Acceleration) {
182
        unitString = QString::fromLatin1("in/min^2");
183
        factor = 25.4 / 3600;
184
    }
185
    else {
186
        // default action for all cases without special treatment:
187
        unitString = quant.getUnit().getString();
188
        factor = 1.0;
189
    }
190

191
    return toLocale(quant, factor, unitString);
192
}
193

194
QString UnitsSchemaImperialBuilding::schemaTranslate(const Quantity& quant,
195
                                                     double& factor,
196
                                                     QString& unitString)
197
{
198
    // this schema expresses distances in feet + inches + fractions
199
    // ex: 3'- 4 1/4" with proper rounding
200
    Unit unit = quant.getUnit();
201
    if (unit == Unit::Length) {
202
        unitString = QString::fromLatin1("in");
203
        factor = 25.4;
204

205
        // Total number of inches to format
206
        double totalInches = std::abs(quant.getValue()) / factor;
207

208
        // minimum denominator (8 for 1/8, 16 for 1/16, etc)
209
        int minden {};
210

211
        // Outputs
212
        int feet {};               // whole feet
213
        int inches {};             // whole inches
214
        int num {}, den {};        // numerator and denominator of fractional val
215
        std::stringstream output;  // output stream
216

217
        // Intermediate values
218
        int ntot {};           // total fractional units
219
        int a {}, b {}, d {};  // used to compute greatest common denominator
220
        int tmp {};            // temporary variable for GCD
221

222
        // Get the current user specified minimum denominator
223
        minden = quant.getFormat().getDenominator();
224

225
        // Compute and round the total number of fractional units
226
        ntot = static_cast<int>(std::round(totalInches * static_cast<double>(minden)));
227

228
        // If this is zero, nothing to do but return
229
        if (ntot == 0) {
230
            return QString::fromLatin1("0");
231
        }
232

233
        // Compute the whole number of feet and remaining units
234
        feet = static_cast<int>(std::floor(ntot / (12 * minden)));
235
        ntot = ntot - 12 * minden * feet;
236

237
        // Compute the remaining number of whole inches
238
        inches = static_cast<int>(std::floor(ntot / minden));
239

240
        // Lastly the fractional quantities
241
        num = ntot - inches * minden;
242
        den = minden;
243

244
        // If numerator is not zero, compute greatest common divisor and reduce
245
        // fraction
246
        if (num != 0) {
247
            // initialize
248
            a = num;
249
            b = den;
250
            while (b != 0) {
251
                tmp = a % b;
252

253
                a = b;
254
                b = tmp;
255
            }
256
            d = a;
257

258
            num /= d;
259
            den /= d;
260
        }
261

262
        // Process into string. Start with negative sign if quantity is less
263
        // than zero
264
        char plusOrMinus {};
265
        if (quant.getValue() < 0) {
266
            output << "-";
267
            plusOrMinus = '-';
268
        }
269
        else {
270
            plusOrMinus = '+';
271
        }
272

273
        bool trailingNumber = false;
274
        // Print feet if we have any
275
        if (feet != 0) {
276
            output << feet << "'";
277
            trailingNumber = true;
278
        }
279
        // Print whole inches if we have any
280
        if (inches != 0) {
281
            if (trailingNumber) {
282
                output << " ";
283
            }
284
            output << inches << "\"";
285
            trailingNumber = true;
286
        }
287
        // Print fractional inches if we have any
288
        if (num != 0) {
289
            if (trailingNumber) {
290
                output << " " << plusOrMinus << " ";
291
            }
292
            output << num << "/" << den << "\"";
293
        }
294

295
        // Done!
296
        return QString::fromLatin1(output.str().c_str());
297
    }
298
    else if (unit == Unit::Angle) {
299
        unitString = QString::fromUtf8("\xC2\xB0");
300
        factor = 1.0;
301
    }
302
    else if (unit == Unit::Area) {
303
        unitString = QString::fromLatin1("sqft");
304
        factor = 92903.04;
305
    }
306
    else if (unit == Unit::Volume) {
307
        unitString = QString::fromLatin1("cft");
308
        factor = 28316846.592;
309
    }
310
    else if (unit == Unit::Velocity) {
311
        unitString = QString::fromLatin1("in/min");
312
        factor = 25.4 / 60;
313
    }
314
    else {
315
        unitString = quant.getUnit().getString();
316
        factor = 1.0;
317
    }
318

319
    return toLocale(quant, factor, unitString);
320
}
321

322
QString UnitsSchemaImperialCivil::schemaTranslate(const Base::Quantity& quant,
323
                                                  double& factor,
324
                                                  QString& unitString)
325
{
326
    //    double UnitValue = std::abs(quant.getValue());
327
    Unit unit = quant.getUnit();
328
    // for imperial user/programmer mind; UnitValue is in internal system, that means
329
    // mm/kg/s. And all combined units have to be calculated from there!
330

331
    // now do special treatment on all cases seems necessary:
332
    if (unit == Unit::Length) {                  // Length handling ============================
333
        unitString = QString::fromLatin1("ft");  // always ft
334
        factor = 304.8;                          // 12 * 25.4
335
    }
336
    else if (unit == Unit::Area) {
337
        unitString = QString::fromLatin1("ft^2");  // always sq.ft
338
        factor = 92903.04;
339
    }
340
    else if (unit == Unit::Volume) {
341
        unitString = QString::fromLatin1("ft^3");  // always cu. ft
342
        factor = 28316846.592;
343
    }
344
    else if (unit == Unit::Mass) {
345
        unitString = QString::fromLatin1("lb");  // always lbs.
346
        factor = 0.45359237;
347
    }
348
    else if (unit == Unit::Pressure) {
349
        unitString = QString::fromLatin1("psi");
350
        factor = 6.894744825494;
351
    }
352
    else if (unit == Unit::Stiffness) {
353
        unitString = QString::fromLatin1("lbf/in");
354
        factor = 4.448222 / 0.0254;
355
    }
356
    else if (unit == Unit::Velocity) {
357
        unitString = QString::fromLatin1("mph");
358
        factor = 447.04;  // 1mm/sec => mph
359
    }
360
    // this schema expresses angles in degrees + minutes + seconds
361
    else if (unit == Unit::Angle) {
362
        unitString = QString::fromUtf8("deg");
363
        QString degreeString = QString::fromUtf8("\xC2\xB0");      // degree symbol
364
        QString minuteString = QString::fromUtf8("\xE2\x80\xB2");  // prime symbol
365
        QString secondString = QString::fromUtf8("\xE2\x80\xB3");  // double prime symbol
366
        factor = 1.0;                                              // 1deg = 1"\xC2\xB0 "
367

368
        double totalDegrees = quant.getValue() / factor;
369
        double wholeDegrees = std::floor(totalDegrees);
370
        double sumMinutes = totalDegrees * 60.0;  // quant as minutes
371
        double rawMinutes = sumMinutes - wholeDegrees * 60.0;
372
        double wholeMinutes = std::floor(rawMinutes);
373
        double sumSeconds = totalDegrees * 3600.0;  // quant as seconds
374
        double rawSeconds = sumSeconds - (wholeDegrees * 3600.0) - (wholeMinutes * 60);
375

376
        int outDeg = static_cast<int>(wholeDegrees);
377
        int outMin = static_cast<int>(wholeMinutes);
378
        int outSec = static_cast<int>(std::round(rawSeconds));
379

380
        std::stringstream output;
381
        output << outDeg << degreeString.toUtf8().constData();
382
        if ((outMin > 0) || (outSec > 0)) {
383
            output << outMin << minuteString.toUtf8().constData();
384
        }
385
        if (outSec > 0) {
386
            output << outSec << secondString.toUtf8().constData();
387
        }
388
        // uncomment this for decimals on seconds
389
        //        if (remainSeconds < (1.0 * pow(10.0,-Base::UnitsApi::getDecimals())) ) {
390
        //            //NOP too small to display
391
        //        } else {
392
        //            output << std::setprecision(Base::UnitsApi::getDecimals()) << std::fixed <<
393
        //                      rawSeconds << secondString.toStdString();
394
        //        }
395
        return QString::fromUtf8(output.str().c_str());
396
    }
397
    else {
398
        // default action for all cases without special treatment:
399
        unitString = quant.getUnit().getString();
400
        factor = 1.0;
401
    }
402

403
    return toLocale(quant, factor, unitString);
404
}
405

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.