~librecad-dev/librecad/librecad

« back to all changes in this revision

Viewing changes to librecad/src/lib/engine/rs_units.cpp

  • Committer: Scott Howard
  • Date: 2014-02-21 19:07:55 UTC
  • Revision ID: showard@debian.org-20140221190755-csjax9wb146hgdq4
first commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************
 
2
**
 
3
** This file is part of the LibreCAD project, a 2D CAD program
 
4
**
 
5
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
 
6
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
 
7
**
 
8
**
 
9
** This file may be distributed and/or modified under the terms of the
 
10
** GNU General Public License version 2 as published by the Free Software
 
11
** Foundation and appearing in the file gpl-2.0.txt included in the
 
12
** packaging of this file.
 
13
**
 
14
** This program is distributed in the hope that it will be useful,
 
15
** but WITHOUT ANY WARRANTY; without even the implied warranty of
 
16
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
17
** GNU General Public License for more details.
 
18
**
 
19
** You should have received a copy of the GNU General Public License
 
20
** along with this program; if not, write to the Free Software
 
21
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 
22
**
 
23
** This copyright notice MUST APPEAR in all copies of the script!
 
24
**
 
25
**********************************************************************/
 
26
 
 
27
 
 
28
#include "rs_units.h"
 
29
 
 
30
#include <QObject>
 
31
 
 
32
#include "rs_math.h"
 
33
#include "rs_debug.h"
 
34
 
 
35
/**
 
36
 * Converts a DXF integer () to a Unit enum.
 
37
 */
 
38
RS2::Unit RS_Units::dxfint2unit(int dxfint) {
 
39
    return (RS2::Unit)dxfint;
 
40
 
 
41
    /*switch(dxfint) {
 
42
    default:
 
43
    case  0:
 
44
        return RS2::None;
 
45
    case  1:
 
46
        return RS2::Inch;
 
47
    case  2:
 
48
        return RS2::Foot;
 
49
    case  3:
 
50
        return RS2::Mile;
 
51
    case  4:
 
52
        return RS2::Millimeter;
 
53
    case  5:
 
54
        return RS2::Centimeter;
 
55
    case  6:
 
56
        return RS2::Meter;
 
57
    case  7:
 
58
        return RS2::Kilometer;
 
59
    case  8:
 
60
        return RS2::Microinch;
 
61
    case  9:
 
62
        return RS2::Mil;
 
63
    case 10:
 
64
        return RS2::Yard;
 
65
    case 11:
 
66
        return RS2::Angstrom;
 
67
    case 12:
 
68
        return RS2::Nanometer;
 
69
    case 13:
 
70
        return RS2::Micron;
 
71
    case 14:
 
72
        return RS2::Decimeter;
 
73
    case 15:
 
74
        return RS2::Decameter;
 
75
    case 16:
 
76
        return RS2::Hectometer;
 
77
    case 17:
 
78
        return RS2::Gigameter;
 
79
    case 18:
 
80
        return RS2::Astro;
 
81
    case 19:
 
82
        return RS2::Lightyear;
 
83
    case 20:
 
84
        return RS2::Parsec;
 
85
}*/
 
86
}
 
87
 
 
88
 
 
89
/**
 
90
 * @return a short string representing the given unit (e.g. "mm")
 
91
 */
 
92
QString RS_Units::unitToSign(RS2::Unit u) {
 
93
    QString ret = "";
 
94
 
 
95
    switch (u) {
 
96
    case RS2::None:
 
97
        ret = "";
 
98
        break;
 
99
    case RS2::Inch:
 
100
        ret = "\"";
 
101
        break;
 
102
    case RS2::Foot:
 
103
        ret = "'";
 
104
        break;
 
105
    case RS2::Mile:
 
106
        ret = "mi";
 
107
        break;
 
108
    case RS2::Millimeter:
 
109
        ret = "mm";
 
110
        break;
 
111
    case RS2::Centimeter:
 
112
        ret = "cm";
 
113
        break;
 
114
    case RS2::Meter:
 
115
        ret = "m";
 
116
        break;
 
117
    case RS2::Kilometer:
 
118
        ret = "km";
 
119
        break;
 
120
    case RS2::Microinch:
 
121
        ret = "µ\"";
 
122
        break;
 
123
    case RS2::Mil:
 
124
        ret = "mil";
 
125
        break;
 
126
    case RS2::Yard:
 
127
        ret = "yd";
 
128
        break;
 
129
    case RS2::Angstrom:
 
130
        ret = "A";
 
131
        break;
 
132
    case RS2::Nanometer:
 
133
        ret = "nm";
 
134
        break;
 
135
    case RS2::Micron:
 
136
        ret = "µm";
 
137
        break;
 
138
    case RS2::Decimeter:
 
139
        ret = "dm";
 
140
        break;
 
141
    case RS2::Decameter:
 
142
        ret = "dam";
 
143
        break;
 
144
    case RS2::Hectometer:
 
145
        ret = "hm";
 
146
        break;
 
147
    case RS2::Gigameter:
 
148
        ret = "Gm";
 
149
        break;
 
150
    case RS2::Astro:
 
151
        ret = "astro";
 
152
        break;
 
153
    case RS2::Lightyear:
 
154
        ret = "ly";
 
155
        break;
 
156
    case RS2::Parsec:
 
157
        ret = "pc";
 
158
        break;
 
159
 
 
160
    default:
 
161
        ret = "";
 
162
        break;
 
163
    }
 
164
 
 
165
    return ret;
 
166
}
 
167
 
 
168
 
 
169
 
 
170
/**
 
171
 * @return a string representing the given unit (e.g. "Millimeter").
 
172
 *      translated if @a t is true (the default).
 
173
 */
 
174
QString RS_Units::unitToString(RS2::Unit u, bool t) {
 
175
    QString ret = "";
 
176
 
 
177
    switch (u) {
 
178
    case RS2::None:
 
179
        ret = t ? QObject::tr("None") : QString("None");
 
180
        break;
 
181
    case RS2::Inch:
 
182
        ret = t ? QObject::tr("Inch") : QString("Inch");
 
183
        break;
 
184
    case RS2::Foot:
 
185
        ret = t ? QObject::tr("Foot") : QString("Foot");
 
186
        break;
 
187
    case RS2::Mile:
 
188
        ret = t ? QObject::tr("Mile") : QString("Mile");
 
189
        break;
 
190
    case RS2::Millimeter:
 
191
        ret = t ? QObject::tr("Millimeter") : QString("Millimeter");
 
192
        break;
 
193
    case RS2::Centimeter:
 
194
        ret = t ? QObject::tr("Centimeter") : QString("Centimeter");
 
195
        break;
 
196
    case RS2::Meter:
 
197
        ret = t ? QObject::tr("Meter") : QString("Meter");
 
198
        break;
 
199
    case RS2::Kilometer:
 
200
        ret = t ? QObject::tr("Kilometer") : QString("Kilometer");
 
201
        break;
 
202
    case RS2::Microinch:
 
203
        ret = t ? QObject::tr("Microinch") : QString("Microinch");
 
204
        break;
 
205
    case RS2::Mil:
 
206
        ret = t ? QObject::tr("Mil") : QString("Mil");
 
207
        break;
 
208
    case RS2::Yard:
 
209
        ret = t ? QObject::tr("Yard") : QString("Yard");
 
210
        break;
 
211
    case RS2::Angstrom:
 
212
        ret = t ? QObject::tr("Angstrom") : QString("Angstrom");
 
213
        break;
 
214
    case RS2::Nanometer:
 
215
        ret = t ? QObject::tr("Nanometer") : QString("Nanometer");
 
216
        break;
 
217
    case RS2::Micron:
 
218
        ret = t ? QObject::tr("Micron") : QString("Micron");
 
219
        break;
 
220
    case RS2::Decimeter:
 
221
        ret = t ? QObject::tr("Decimeter") : QString("Decimeter");
 
222
        break;
 
223
    case RS2::Decameter:
 
224
        ret = t ? QObject::tr("Decameter") : QString("Decameter");
 
225
        break;
 
226
    case RS2::Hectometer:
 
227
        ret = t ? QObject::tr("Hectometer") : QString("Hectometer");
 
228
        break;
 
229
    case RS2::Gigameter:
 
230
        ret = t ? QObject::tr("Gigameter") : QString("Gigameter");
 
231
        break;
 
232
    case RS2::Astro:
 
233
        ret = t ? QObject::tr("Astro") : QString("Astro");
 
234
        break;
 
235
    case RS2::Lightyear:
 
236
        ret = t ? QObject::tr("Lightyear") : QString("Lightyear");
 
237
        break;
 
238
    case RS2::Parsec:
 
239
        ret = t ? QObject::tr("Parsec") : QString("Parsec");
 
240
        break;
 
241
 
 
242
    default:
 
243
        ret = "";
 
244
        break;
 
245
    }
 
246
 
 
247
    return ret;
 
248
}
 
249
 
 
250
 
 
251
 
 
252
/**
 
253
 * Converts a string into a unit enum.
 
254
 */
 
255
RS2::Unit RS_Units::stringToUnit(const QString& u) {
 
256
    RS2::Unit ret = RS2::None;
 
257
 
 
258
    if (u=="None") {
 
259
        ret = RS2::None;
 
260
    } else if (u==QObject::tr("Inch")) {
 
261
        ret = RS2::Inch;
 
262
    } else if (u==QObject::tr("Foot")) {
 
263
        ret = RS2::Foot;
 
264
    } else if (u==QObject::tr("Mile")) {
 
265
        ret = RS2::Mile;
 
266
    } else if (u==QObject::tr("Millimeter")) {
 
267
        ret = RS2::Millimeter;
 
268
    } else if (u==QObject::tr("Centimeter")) {
 
269
        ret = RS2::Centimeter;
 
270
    } else if (u==QObject::tr("Meter")) {
 
271
        ret = RS2::Meter;
 
272
    } else if (u==QObject::tr("Kilometer")) {
 
273
        ret = RS2::Kilometer;
 
274
    } else if (u==QObject::tr("Microinch")) {
 
275
        ret = RS2::Microinch;
 
276
    } else if (u==QObject::tr("Mil")) {
 
277
        ret = RS2::Mil;
 
278
    } else if (u==QObject::tr("Yard")) {
 
279
        ret = RS2::Yard;
 
280
    } else if (u==QObject::tr("Angstrom")) {
 
281
        ret = RS2::Angstrom;
 
282
    } else if (u==QObject::tr("Nanometer")) {
 
283
        ret = RS2::Nanometer;
 
284
    } else if (u==QObject::tr("Micron")) {
 
285
        ret = RS2::Micron;
 
286
    } else if (u==QObject::tr("Decimeter")) {
 
287
        ret = RS2::Decimeter;
 
288
    } else if (u==QObject::tr("Decameter")) {
 
289
        ret = RS2::Decameter;
 
290
    } else if (u==QObject::tr("Hectometer")) {
 
291
        ret = RS2::Hectometer;
 
292
    } else if (u==QObject::tr("Gigameter")) {
 
293
        ret = RS2::Gigameter;
 
294
    } else if (u==QObject::tr("Astro")) {
 
295
        ret = RS2::Astro;
 
296
    } else if (u==QObject::tr("Lightyear")) {
 
297
        ret = RS2::Lightyear;
 
298
    } else if (u==QObject::tr("Parsec")) {
 
299
        ret = RS2::Parsec;
 
300
    }
 
301
 
 
302
    return ret;
 
303
}
 
304
 
 
305
 
 
306
 
 
307
 
 
308
/**
 
309
 * @return true: the unit is metric, false: the unit is imperial.
 
310
 */
 
311
bool RS_Units::isMetric(RS2::Unit u) {
 
312
    if (u==RS2::Millimeter ||
 
313
            u==RS2::Centimeter ||
 
314
            u==RS2::Meter ||
 
315
            u==RS2::Kilometer ||
 
316
            u==RS2::Angstrom ||
 
317
            u==RS2::Nanometer ||
 
318
            u==RS2::Micron ||
 
319
            u==RS2::Decimeter ||
 
320
            u==RS2::Decameter ||
 
321
            u==RS2::Hectometer ||
 
322
            u==RS2::Gigameter ||
 
323
            u==RS2::Astro ||
 
324
            u==RS2::Lightyear ||
 
325
            u==RS2::Parsec) {
 
326
 
 
327
        return true;
 
328
    } else {
 
329
        return false;
 
330
    }
 
331
}
 
332
 
 
333
 
 
334
 
 
335
/**
 
336
 * @return factor to convert the given unit to Millimeters.
 
337
 */
 
338
double RS_Units::getFactorToMM(RS2::Unit u) {
 
339
    double ret = 1.0;
 
340
 
 
341
    switch (u) {
 
342
    case RS2::None:
 
343
        ret = 1.0;
 
344
        break;
 
345
    case RS2::Inch:
 
346
        ret = 25.4;
 
347
        break;
 
348
    case RS2::Foot:
 
349
        ret = 304.8;
 
350
        break;
 
351
    case RS2::Mile:
 
352
        ret = 1609344;
 
353
        break;
 
354
    case RS2::Millimeter:
 
355
        ret = 1.0;
 
356
        break;
 
357
    case RS2::Centimeter:
 
358
        ret = 10;
 
359
        break;
 
360
    case RS2::Meter:
 
361
        ret = 1000;
 
362
        break;
 
363
    case RS2::Kilometer:
 
364
        ret = 1000000;
 
365
        break;
 
366
    case RS2::Microinch:
 
367
        ret = 0.0000254;
 
368
        break;
 
369
    case RS2::Mil:
 
370
        ret = 0.0254;
 
371
        break;
 
372
    case RS2::Yard:
 
373
        ret = 914.4;
 
374
        break;
 
375
    case RS2::Angstrom:
 
376
        ret = 0.0000001;
 
377
        break;
 
378
    case RS2::Nanometer:
 
379
        ret = 0.000001;
 
380
        break;
 
381
    case RS2::Micron:
 
382
        ret = 0.001;
 
383
        break;
 
384
    case RS2::Decimeter:
 
385
        ret = 100.0;
 
386
        break;
 
387
    case RS2::Decameter:
 
388
        ret = 10000.0;
 
389
        break;
 
390
    case RS2::Hectometer:
 
391
        ret = 100000.0;
 
392
        break;
 
393
    case RS2::Gigameter:
 
394
        ret = 1000000000.0;
 
395
        break;
 
396
    case RS2::Astro:
 
397
        ret = 149600000000000.0;
 
398
        break;
 
399
    case RS2::Lightyear:
 
400
        ret = 9460731798000000000.0;
 
401
        break;
 
402
    case RS2::Parsec:
 
403
        ret = 30857000000000000000.0;
 
404
        break;
 
405
    default:
 
406
        ret = 1.0;
 
407
        break;
 
408
    }
 
409
 
 
410
    return ret;
 
411
}
 
412
 
 
413
 
 
414
/**
 
415
 * Converts the given value 'val' from unit 'src' to unit 'dest'.
 
416
 */
 
417
double RS_Units::convert(double val, RS2::Unit src, RS2::Unit dest) {
 
418
    if (getFactorToMM(dest)>0.0) {
 
419
        return (val*getFactorToMM(src))/getFactorToMM(dest);
 
420
    } else {
 
421
        RS_DEBUG->print(RS_Debug::D_WARNING,
 
422
                        "RS_Units::convert: invalid factor");
 
423
        return val;
 
424
    }
 
425
}
 
426
 
 
427
 
 
428
 
 
429
/**
 
430
 * Converts the given vector 'val' from unit 'src' to unit 'dest'.
 
431
 */
 
432
RS_Vector RS_Units::convert(const RS_Vector val, RS2::Unit src, RS2::Unit dest) {
 
433
    return RS_Vector(convert(val.x, src, dest),
 
434
                     convert(val.y, src, dest)
 
435
#ifndef RS_VECTOR2D
 
436
                     , convert(val.z, src, dest)
 
437
#endif
 
438
                     );
 
439
}
 
440
 
 
441
 
 
442
 
 
443
/**
 
444
 * Formats the given length in the given format.
 
445
 *
 
446
 * @param length The length in the current unit of the drawing.
 
447
 * @param format Format of the string.
 
448
 * @param prec Precisision of the value (e.g. 0.001 or 1/128 = 0.0078125)
 
449
 & @param showUnit Append unit to the value.
 
450
 */
 
451
QString RS_Units::formatLinear(double length, RS2::Unit unit,
 
452
                                 RS2::LinearFormat format,
 
453
                                 int prec, bool showUnit) {
 
454
    QString ret;
 
455
 
 
456
    // unit appended to value (e.g. 'mm'):
 
457
    /*QString unitString = "";
 
458
    if (showUnit) {
 
459
        unitString = unitToSign(unit);
 
460
}*/
 
461
 
 
462
    // barbarian display: show as fraction:
 
463
    switch (format) {
 
464
    case RS2::Scientific:
 
465
        ret = formatScientific(length, unit, prec, showUnit);
 
466
        break;
 
467
 
 
468
    case RS2::Decimal:
 
469
        ret = formatDecimal(length, unit, prec, showUnit);
 
470
        break;
 
471
 
 
472
    case RS2::Engineering:
 
473
        ret = formatEngineering(length, unit, prec, showUnit);
 
474
        break;
 
475
 
 
476
    case RS2::Architectural:
 
477
        ret = formatArchitectural(length, unit, prec, showUnit);
 
478
        break;
 
479
 
 
480
    case RS2::Fractional:
 
481
        ret = formatFractional(length, unit, prec, showUnit);
 
482
        break;
 
483
 
 
484
    default:
 
485
        RS_DEBUG->print(RS_Debug::D_WARNING,
 
486
                        "RS_Units::formatLinear: Unknown format");
 
487
        ret = "";
 
488
        break;
 
489
    }
 
490
 
 
491
    return ret;
 
492
}
 
493
 
 
494
 
 
495
 
 
496
/**
 
497
 * Formats the given length in scientific format (e.g. 2.5E7).
 
498
 *
 
499
 * @param length The length in the current unit of the drawing.
 
500
 * @param prec Precisision of the value (e.g. 0.001 or 1/128 = 0.0078125)
 
501
 & @param showUnit Append unit to the value.
 
502
 */
 
503
QString RS_Units::formatScientific(double length, RS2::Unit unit,
 
504
                                     int prec, bool showUnit) {
 
505
 
 
506
    QString ret;
 
507
 
 
508
    // unit appended to value (e.g. 'mm'):
 
509
    QString unitString = "";
 
510
    if (showUnit) {
 
511
        unitString = unitToSign(unit);
 
512
    }
 
513
 
 
514
    ret = QString("%1%2").arg(length,0,'E', prec).arg(unitString);
 
515
 
 
516
    return ret;
 
517
}
 
518
 
 
519
 
 
520
 
 
521
/**
 
522
 * Formats the given length in decimal (normal) format (e.g. 2.5).
 
523
 *
 
524
 * @param length The length in the current unit of the drawing.
 
525
 * @param prec Precisision of the value (e.g. 0.001)
 
526
 & @param showUnit Append unit to the value.
 
527
 */
 
528
QString RS_Units::formatDecimal(double length, RS2::Unit unit,
 
529
                                  int prec, bool showUnit) {
 
530
 
 
531
    QString ret;
 
532
 
 
533
    // unit appended to value (e.g. 'mm'):
 
534
    QString unitString = "";
 
535
    if (showUnit) {
 
536
        unitString = unitToSign(unit);
 
537
    }
 
538
 
 
539
    ret = RS_Math::doubleToString(length, prec);
 
540
    if(showUnit) {
 
541
        ret+=unitString;
 
542
    }
 
543
 
 
544
    return ret;
 
545
}
 
546
 
 
547
 
 
548
 
 
549
/**
 
550
 * Formats the given length in engineering format (e.g. 5' 4.5").
 
551
 *
 
552
 * @param length The length in the current unit of the drawing.
 
553
 * @param prec Precisision of the value (e.g. 0.001 or 1/128 = 0.0078125)
 
554
 & @param showUnit Append unit to the value.
 
555
 */
 
556
QString RS_Units::formatEngineering(double length, RS2::Unit /*unit*/,
 
557
                                      int prec, bool /*showUnit*/) {
 
558
    QString ret;
 
559
 
 
560
    bool sign = (length<0.0);
 
561
    int feet = (int)floor(fabs(length)/12);
 
562
    double inches = fabs(length) - feet*12;
 
563
 
 
564
    QString sInches = RS_Math::doubleToString(inches, prec);
 
565
 
 
566
    if (sInches=="12") {
 
567
        feet++;
 
568
        sInches="0";
 
569
    }
 
570
 
 
571
    if (feet!=0) {
 
572
        ret = QString("%1'-%2\"").arg(feet).arg(sInches);
 
573
    } else {
 
574
        ret = QString("%1\"").arg(sInches);
 
575
    }
 
576
 
 
577
    if (sign) {
 
578
        ret = "-" + ret;
 
579
    }
 
580
 
 
581
    return ret;
 
582
}
 
583
 
 
584
 
 
585
 
 
586
/**
 
587
 * Formats the given length in architectural format (e.g. 5' 4 1/2").
 
588
 *
 
589
 * @param length The length in the current unit of the drawing.
 
590
 * @param prec Precisision of the value (e.g. 0.001 or 1/128 = 0.0078125)
 
591
 & @param showUnit Append unit to the value.
 
592
 */
 
593
QString RS_Units::formatArchitectural(double length, RS2::Unit /*unit*/,
 
594
                                        int prec, bool showUnit) {
 
595
    QString ret;
 
596
    bool neg = (length<0.0);
 
597
 
 
598
    int feet = (int)floor(fabs(length)/12);
 
599
    double inches = fabs(length) - feet*12;
 
600
 
 
601
    QString sInches = formatFractional(inches, RS2::Inch, prec, showUnit);
 
602
 
 
603
    if (sInches=="12") {
 
604
        feet++;
 
605
        sInches = "0";
 
606
    }
 
607
 
 
608
    if (neg) {
 
609
        ret = QString("-%1'-%2\"").arg(feet).arg(sInches);
 
610
    } else {
 
611
        ret = QString("%1'-%2\"").arg(feet).arg(sInches);
 
612
    }
 
613
 
 
614
    return ret;
 
615
}
 
616
 
 
617
 
 
618
 
 
619
/**
 
620
 * Formats the given length in fractional (barbarian) format (e.g. 5' 3 1/64").
 
621
 *
 
622
 * @param length The length in the current unit of the drawing.
 
623
 * @param unit Should be inches.
 
624
 * @param prec Precisision of the value (e.g. 0.001 or 1/128 = 0.0078125)
 
625
 & @param showUnit Append unit to the value.
 
626
 */
 
627
QString RS_Units::formatFractional(double length, RS2::Unit /*unit*/,
 
628
                                     int prec, bool /*showUnit*/) {
 
629
 
 
630
    QString ret;
 
631
 
 
632
    int num;            // number of complete inches (num' 7/128")
 
633
    int nominator;      // number of fractions (nominator/128)
 
634
    int denominator;    // (4/denominator)
 
635
 
 
636
    // sign:
 
637
    QString neg = "";
 
638
    if(length < 0) {
 
639
        neg = "-";
 
640
        length = fabs(length);
 
641
    }
 
642
 
 
643
    num = (int)floor(length);
 
644
 
 
645
    denominator = (int)RS_Math::pow(2, prec);
 
646
    nominator = RS_Math::round((length-num)*denominator);
 
647
 
 
648
    // fraction rounds up to 1:
 
649
    if (nominator==denominator) {
 
650
        nominator=0;
 
651
        denominator=0;
 
652
        ++num;
 
653
    }
 
654
 
 
655
    // Simplify the fraction
 
656
    if (nominator!=0 && denominator!=0) {
 
657
        int gcd = RS_Math::findGCD(nominator, denominator);
 
658
        if (gcd!=0) {
 
659
            nominator = nominator / gcd;
 
660
            denominator = denominator / gcd;
 
661
        } else {
 
662
            RS_DEBUG->print(RS_Debug::D_WARNING,
 
663
                                "RS_Units::formatFractional: invalid gcd");
 
664
            nominator = 0;
 
665
            denominator = 0;
 
666
        }
 
667
    }
 
668
 
 
669
    if( num!=0 && nominator!=0 ) {
 
670
        ret = QString("%1%2 %3/%4").arg(neg).arg(num).arg(nominator).arg(denominator);
 
671
    } else if(nominator!=0) {
 
672
        ret = QString("%1%2/%3").arg(neg).arg(nominator).arg(denominator);
 
673
    } else if(num!=0) {
 
674
        ret = QString("%1%2").arg(neg).arg(num);
 
675
    } else {
 
676
        ret = "0";
 
677
    }
 
678
 
 
679
    return ret;
 
680
}
 
681
 
 
682
 
 
683
 
 
684
 
 
685
 
 
686
/**
 
687
 * Formats the given angle with the given format.
 
688
 *
 
689
 * @param angle The angle (always in rad).
 
690
 * @param format Format of the string.
 
691
 * @param prec Precisision of the value (e.g. 0.001 or 1/128 = 0.0078125)
 
692
 *
 
693
 * @ret String with the formatted angle.
 
694
 */
 
695
QString RS_Units::formatAngle(double angle, RS2::AngleFormat format,
 
696
                                int prec) {
 
697
 
 
698
    QString ret;
 
699
    double value;
 
700
 
 
701
    switch (format) {
 
702
    case RS2::DegreesDecimal:
 
703
    case RS2::DegreesMinutesSeconds:
 
704
        value = RS_Math::rad2deg(angle);
 
705
        break;
 
706
    case RS2::Radians:
 
707
        value = angle;
 
708
        break;
 
709
    case RS2::Gradians:
 
710
        value = RS_Math::rad2gra(angle);
 
711
        break;
 
712
    default:
 
713
        RS_DEBUG->print(RS_Debug::D_WARNING,
 
714
                        "RS_Units::formatAngle: Unknown Angle Unit");
 
715
        return "";
 
716
        break;
 
717
    }
 
718
 
 
719
    switch (format) {
 
720
    case RS2::DegreesDecimal:
 
721
    case RS2::Radians:
 
722
    case RS2::Gradians:
 
723
        ret = RS_Math::doubleToString(value, prec);
 
724
        if (format==RS2::DegreesDecimal)
 
725
            ret+=QChar(0xB0);
 
726
        if (format==RS2::Radians)
 
727
            ret+="r";
 
728
        if (format==RS2::Gradians)
 
729
            ret+="g";
 
730
        break;
 
731
 
 
732
    case RS2::DegreesMinutesSeconds: {
 
733
            int vDegrees, vMinutes;
 
734
            double vSeconds;
 
735
            QString degrees, minutes, seconds;
 
736
 
 
737
            vDegrees = (int)floor(value);
 
738
            vMinutes = (int)floor((value - vDegrees) * 60.0);
 
739
            vSeconds = (value - vDegrees - (vMinutes/60.0)) * 3600.0;
 
740
 
 
741
            seconds = RS_Math::doubleToString(vSeconds, (prec>1 ? prec-2 : 0));
 
742
 
 
743
            if(seconds=="60") {
 
744
                seconds="0";
 
745
                ++vMinutes;
 
746
                if(vMinutes==60) {
 
747
                    vMinutes=0;
 
748
                    ++vDegrees;
 
749
                }
 
750
            }
 
751
 
 
752
            if (prec==0 && vMinutes>=30.0) {
 
753
                vDegrees++;
 
754
            } else if (prec==1 && vSeconds>=30.0) {
 
755
                vMinutes++;
 
756
            }
 
757
 
 
758
            degrees.setNum(vDegrees);
 
759
            minutes.setNum(vMinutes);
 
760
 
 
761
            switch (prec) {
 
762
            case 0:
 
763
                ret = degrees + QChar(0xB0);
 
764
                break;
 
765
            case 1:
 
766
                ret = degrees + QChar(0xB0) + " " + minutes + "'";
 
767
                break;
 
768
            default:
 
769
                ret = degrees + QChar(0xB0) + " " + minutes + "' "
 
770
                      + seconds + "\"";
 
771
                break;
 
772
            }
 
773
        }
 
774
        break;
 
775
 
 
776
    default:
 
777
        break;
 
778
    }
 
779
 
 
780
    return ret;
 
781
}
 
782
 
 
783
/**
 
784
 * Converts the given number from a DXF file into an AngleFormat enum.
 
785
 *
 
786
 * @param num $DIMAUNIT from DXF (0: decimal deg, 1: deg/min/sec, 2: gradians,
 
787
 *                                3: radians, 4: surveyor's units)
 
788
 *
 
789
 * @ret Matching AngleFormat enum value.
 
790
 */
 
791
RS2::AngleFormat RS_Units::numberToAngleFormat(int num) {
 
792
 
 
793
    RS2::AngleFormat af;
 
794
 
 
795
    switch (num) {
 
796
    default:
 
797
    case 0:
 
798
        af = RS2::DegreesDecimal;
 
799
        break;
 
800
    case 1:
 
801
        af = RS2::DegreesMinutesSeconds;
 
802
        break;
 
803
    case 2:
 
804
        af = RS2::Gradians;
 
805
        break;
 
806
    case 3:
 
807
        af = RS2::Radians;
 
808
        break;
 
809
    case 4:
 
810
        af = RS2::Surveyors;
 
811
        break;
 
812
    }
 
813
 
 
814
    return af;
 
815
}
 
816
 
 
817
 
 
818
/**
 
819
 * @return Size of the given paper format.
 
820
 */
 
821
RS_Vector RS_Units::paperFormatToSize(RS2::PaperFormat p) {
 
822
    RS_Vector ret(false);
 
823
 
 
824
    switch (p) {
 
825
    case RS2::Custom:
 
826
        ret = RS_Vector(0.0, 0.0);
 
827
        break;
 
828
    case RS2::Letter:
 
829
        ret = RS_Vector(215.9, 279.4);
 
830
        break;
 
831
    case RS2::Legal:
 
832
        ret = RS_Vector(215.9, 355.6);
 
833
        break;
 
834
    case RS2::Executive:
 
835
        ret = RS_Vector(190.5, 254.0);
 
836
        break;
 
837
    case RS2::A0:
 
838
        ret = RS_Vector(841.0, 1189.0);
 
839
        break;
 
840
    case RS2::A1:
 
841
        ret = RS_Vector(594.0, 841.0);
 
842
        break;
 
843
    case RS2::A2:
 
844
        ret = RS_Vector(420.0, 594.0);
 
845
        break;
 
846
    case RS2::A3:
 
847
        ret = RS_Vector(297.0, 420.0);
 
848
        break;
 
849
    case RS2::A4:
 
850
        ret = RS_Vector(210.0, 297.0);
 
851
        break;
 
852
    case RS2::A5:
 
853
        ret = RS_Vector(148.0, 210.0);
 
854
        break;
 
855
    case RS2::A6:
 
856
        ret = RS_Vector(105.0, 148.0);
 
857
        break;
 
858
    case RS2::A7:
 
859
        ret = RS_Vector(74.0, 105.0);
 
860
        break;
 
861
    case RS2::A8:
 
862
        ret = RS_Vector(52.0, 74.0);
 
863
        break;
 
864
    case RS2::A9:
 
865
        ret = RS_Vector(37.0, 52.0);
 
866
        break;
 
867
        /*case RS2::A10:
 
868
            ret = RS_Vector(26.0, 37.0);
 
869
            break;*/
 
870
    case RS2::B0:
 
871
        ret = RS_Vector(1000.0, 1414.0);
 
872
        break;
 
873
    case RS2::B1:
 
874
        ret = RS_Vector(707.0, 1000.0);
 
875
        break;
 
876
    case RS2::B2:
 
877
        ret = RS_Vector(500.0, 707.0);
 
878
        break;
 
879
    case RS2::B3:
 
880
        ret = RS_Vector(353.0, 500.0);
 
881
        break;
 
882
    case RS2::B4:
 
883
        ret = RS_Vector(250.0, 353.0);
 
884
        break;
 
885
    case RS2::B5:
 
886
        ret = RS_Vector(176.0, 250.0);
 
887
        break;
 
888
    case RS2::B6:
 
889
        ret = RS_Vector(125.0, 176.0);
 
890
        break;
 
891
    case RS2::B7:
 
892
        ret = RS_Vector(88.0, 125.0);
 
893
        break;
 
894
    case RS2::B8:
 
895
        ret = RS_Vector(62.0, 88.0);
 
896
        break;
 
897
    case RS2::B9:
 
898
        ret = RS_Vector(44.0, 62.0);
 
899
        break;
 
900
    case RS2::B10:
 
901
        ret = RS_Vector(31.0, 44.0);
 
902
        break;
 
903
        /*
 
904
          case RS2::C0:
 
905
              ret = RS_Vector(917.0, 1297.0);
 
906
              break;
 
907
          case RS2::C1:
 
908
              ret = RS_Vector(648.0, 917.0);
 
909
              break;
 
910
          case RS2::C2:
 
911
              ret = RS_Vector(458.0, 648.0);
 
912
              break;
 
913
          case RS2::C3:
 
914
              ret = RS_Vector(324.0, 458.0);
 
915
              break;
 
916
          case RS2::C4:
 
917
              ret = RS_Vector(229.0, 324.0);
 
918
              break;
 
919
          case RS2::C5:
 
920
              ret = RS_Vector(162.0, 229.0);
 
921
              break;
 
922
          case RS2::C6:
 
923
              ret = RS_Vector(114.0, 162.0);
 
924
              break;
 
925
          case RS2::C7:
 
926
              ret = RS_Vector(81.0, 114.0);
 
927
              break;
 
928
          case RS2::C8:
 
929
              ret = RS_Vector(57.0, 81.0);
 
930
              break;
 
931
          case RS2::C9:
 
932
              ret = RS_Vector(40.0, 57.0);
 
933
              break;
 
934
          case RS2::C10:
 
935
              ret = RS_Vector(28.0, 40.0);
 
936
              break;
 
937
        */
 
938
    case RS2::C5E:
 
939
        ret = RS_Vector(163.0, 229.0);
 
940
        break;
 
941
    case RS2::Comm10E:
 
942
        ret = RS_Vector(105.0, 241.0);
 
943
        break;
 
944
    case RS2::DLE:
 
945
        ret = RS_Vector(110.0, 220.0);
 
946
        break;
 
947
    case RS2::Folio:
 
948
        ret = RS_Vector(210.0, 330.0);
 
949
        break;
 
950
    //case RS2::Ledger:
 
951
    //    ret = RS_Vector(432.0, 279.0);
 
952
    //    break;
 
953
    case RS2::Tabloid:
 
954
        ret = RS_Vector(279.0, 432.0);
 
955
        break;
 
956
 
 
957
    case RS2::Arch_A:
 
958
    return RS_Vector(229.,305.);
 
959
    case RS2::Arch_B:
 
960
    return RS_Vector(305.,457.);
 
961
    case RS2::Arch_C:
 
962
    return RS_Vector(457.,610.);
 
963
    case RS2::Arch_D:
 
964
    return RS_Vector(610.,914.);
 
965
    case RS2::Arch_E:
 
966
    return RS_Vector(914.,1219.);
 
967
    case RS2::Arch_E1:
 
968
    return RS_Vector(762.,1067.);
 
969
    case RS2::Arch_E2:
 
970
    return RS_Vector(660.,965.);
 
971
    case RS2::Arch_E3:
 
972
    return RS_Vector(686.,991.);
 
973
 
 
974
    case RS2::NPageSize:
 
975
        return RS_Vector(0.0, 0.0);
 
976
        break;
 
977
    default:
 
978
        break;
 
979
    }
 
980
 
 
981
    return ret;
 
982
}
 
983
 
 
984
 
 
985
 
 
986
/**
 
987
 * Gets the paper format which matches the given size. If no
 
988
 * format matches, RS2::Custom is returned.
 
989
 */
 
990
RS2::PaperFormat RS_Units::paperSizeToFormat(const RS_Vector s) {
 
991
    RS_Vector ts1;
 
992
    RS_Vector ts2;
 
993
 
 
994
    for (int i=(int)RS2::Custom; i<=(int)RS2::NPageSize; ++i) {
 
995
        ts1 = RS_Units::paperFormatToSize((RS2::PaperFormat)i);
 
996
        ts2 = RS_Vector(ts1.y, ts1.x);
 
997
 
 
998
        if (ts1.distanceTo(s)<1.0e-4 || ts2.distanceTo(s)<1.0e-4) {
 
999
            return (RS2::PaperFormat)i;
 
1000
        }
 
1001
    }
 
1002
 
 
1003
    return RS2::Custom;
 
1004
}
 
1005
 
 
1006
 
 
1007
 
 
1008
/**
 
1009
 * Converts a paper format to a string (e.g. for a combobox).
 
1010
 */
 
1011
QString RS_Units::paperFormatToString(RS2::PaperFormat p) {
 
1012
    QString ret = "";
 
1013
 
 
1014
    switch (p) {
 
1015
    case RS2::Custom:
 
1016
        ret = "Custom";
 
1017
        break;
 
1018
    case RS2::Letter:
 
1019
        ret = "Letter";
 
1020
        break;
 
1021
    case RS2::Legal:
 
1022
        ret = "Legal";
 
1023
        break;
 
1024
    case RS2::Executive:
 
1025
        ret = "Executive";
 
1026
        break;
 
1027
    case RS2::A0:
 
1028
        ret = "A0";
 
1029
        break;
 
1030
    case RS2::A1:
 
1031
        ret = "A1";
 
1032
        break;
 
1033
    case RS2::A2:
 
1034
        ret = "A2";
 
1035
        break;
 
1036
    case RS2::A3:
 
1037
        ret = "A3";
 
1038
        break;
 
1039
    case RS2::A4:
 
1040
        ret = "A4";
 
1041
        break;
 
1042
    case RS2::A5:
 
1043
        ret = "A5";
 
1044
        break;
 
1045
    case RS2::A6:
 
1046
        ret = "A6";
 
1047
        break;
 
1048
    case RS2::A7:
 
1049
        ret = "A7";
 
1050
        break;
 
1051
    case RS2::A8:
 
1052
        ret = "A8";
 
1053
        break;
 
1054
    case RS2::A9:
 
1055
        ret = "A9";
 
1056
        break;
 
1057
    case RS2::B0:
 
1058
        ret = "B0";
 
1059
        break;
 
1060
    case RS2::B1:
 
1061
        ret = "B1";
 
1062
        break;
 
1063
    case RS2::B2:
 
1064
        ret = "B2";
 
1065
        break;
 
1066
    case RS2::B3:
 
1067
        ret = "B3";
 
1068
        break;
 
1069
    case RS2::B4:
 
1070
        ret = "B4";
 
1071
        break;
 
1072
    case RS2::B5:
 
1073
        ret = "B5";
 
1074
        break;
 
1075
    case RS2::B6:
 
1076
        ret = "B6";
 
1077
        break;
 
1078
    case RS2::B7:
 
1079
        ret = "B7";
 
1080
        break;
 
1081
    case RS2::B8:
 
1082
        ret = "B8";
 
1083
        break;
 
1084
    case RS2::B9:
 
1085
        ret = "B9";
 
1086
        break;
 
1087
    case RS2::B10:
 
1088
        ret = "B10";
 
1089
        break;
 
1090
        /*
 
1091
           case RS2::C0:
 
1092
               ret = "C0";
 
1093
               break;
 
1094
           case RS2::C1:
 
1095
               ret = "C1";
 
1096
               break;
 
1097
           case RS2::C2:
 
1098
               ret = "C2";
 
1099
               break;
 
1100
           case RS2::C3:
 
1101
               ret = "C3";
 
1102
               break;
 
1103
           case RS2::C4:
 
1104
               ret = "C4";
 
1105
               break;
 
1106
           case RS2::C5:
 
1107
               ret = "C5";
 
1108
               break;
 
1109
           case RS2::C6:
 
1110
               ret = "C6";
 
1111
               break;
 
1112
           case RS2::C7:
 
1113
               ret = "C7";
 
1114
               break;
 
1115
           case RS2::C8:
 
1116
               ret = "C8";
 
1117
               break;
 
1118
           case RS2::C9:
 
1119
               ret = "C9";
 
1120
               break;
 
1121
           case RS2::C10:
 
1122
               ret = "C10";
 
1123
               break;
 
1124
        */
 
1125
    case RS2::C5E:
 
1126
        ret = "C5E";
 
1127
        break;
 
1128
    case RS2::Comm10E:
 
1129
        ret = "Comm10E";
 
1130
        break;
 
1131
    case RS2::DLE:
 
1132
        ret = "DLE";
 
1133
        break;
 
1134
    case RS2::Folio:
 
1135
        ret = "Folio";
 
1136
        break;
 
1137
    //case RS2::Ledger:
 
1138
    //    ret = "Ledger";
 
1139
    //    break;
 
1140
    case RS2::Tabloid:
 
1141
        ret = "Tabloid";
 
1142
        break;
 
1143
    case RS2::Arch_A:
 
1144
    return QString("Arch A");
 
1145
    case RS2::Arch_B:
 
1146
    return QString("Arch B");
 
1147
    case RS2::Arch_C:
 
1148
    return QString("Arch C");
 
1149
    case RS2::Arch_D:
 
1150
    return QString("Arch D");
 
1151
    case RS2::Arch_E:
 
1152
    return QString("Arch E");
 
1153
    case RS2::Arch_E1:
 
1154
    return QString("Arch E1");
 
1155
    case RS2::Arch_E2:
 
1156
    return QString("Arch E2");
 
1157
    case RS2::Arch_E3:
 
1158
    return QString("Arch E3");
 
1159
 
 
1160
    case RS2::NPageSize:
 
1161
        ret = "NPageSize";
 
1162
        break;
 
1163
    default:
 
1164
        break;
 
1165
    }
 
1166
 
 
1167
    return ret;
 
1168
}
 
1169
 
 
1170
 
 
1171
 
 
1172
/**
 
1173
 * Converts a string to a paper format.
 
1174
 */
 
1175
RS2::PaperFormat RS_Units::stringToPaperFormat(const QString& p) {
 
1176
    QString ls = p.toLower();
 
1177
    RS2::PaperFormat ret = RS2::Custom;
 
1178
 
 
1179
    if (p=="custom") {
 
1180
        ret = RS2::Custom;
 
1181
    } else if (p=="letter") {
 
1182
        ret = RS2::Letter;
 
1183
    } else if (p=="legal") {
 
1184
        ret = RS2::Legal;
 
1185
    } else if (p=="executive") {
 
1186
        ret = RS2::Executive;
 
1187
    } else if (p=="a0") {
 
1188
        ret = RS2::A0;
 
1189
    } else if (p=="a1") {
 
1190
        ret = RS2::A1;
 
1191
    } else if (p=="a2") {
 
1192
        ret = RS2::A2;
 
1193
    } else if (p=="a3") {
 
1194
        ret = RS2::A3;
 
1195
    } else if (p=="a4") {
 
1196
        ret = RS2::A4;
 
1197
    } else if (p=="a5") {
 
1198
        ret = RS2::A5;
 
1199
    } else if (p=="a6") {
 
1200
        ret = RS2::A6;
 
1201
    } else if (p=="a7") {
 
1202
        ret = RS2::A7;
 
1203
    } else if (p=="a8") {
 
1204
        ret = RS2::A8;
 
1205
    } else if (p=="a9") {
 
1206
        ret = RS2::A9;
 
1207
    } else if (p=="b0") {
 
1208
        ret = RS2::B0;
 
1209
    } else if (p=="b1") {
 
1210
        ret = RS2::B1;
 
1211
    } else if (p=="b2") {
 
1212
        ret = RS2::B2;
 
1213
    } else if (p=="b3") {
 
1214
        ret = RS2::B3;
 
1215
    } else if (p=="b4") {
 
1216
        ret = RS2::B4;
 
1217
    } else if (p=="b5") {
 
1218
        ret = RS2::B5;
 
1219
    } else if (p=="b6") {
 
1220
        ret = RS2::B6;
 
1221
    } else if (p=="b7") {
 
1222
        ret = RS2::B7;
 
1223
    } else if (p=="b8") {
 
1224
        ret = RS2::B8;
 
1225
    } else if (p=="b9") {
 
1226
        ret = RS2::B9;
 
1227
    } else if (p=="b10") {
 
1228
        ret = RS2::B10;
 
1229
    }
 
1230
    /*else if (p=="c0") {
 
1231
           ret = RS2::C0;
 
1232
       } else if (p=="c1") {
 
1233
           ret = RS2::C1;
 
1234
       } else if (p=="c2") {
 
1235
           ret = RS2::C2;
 
1236
       } else if (p=="c3") {
 
1237
           ret = RS2::C3;
 
1238
       } else if (p=="c4") {
 
1239
           ret = RS2::C4;
 
1240
       } else if (p=="c5") {
 
1241
           ret = RS2::C5;
 
1242
       } else if (p=="c6") {
 
1243
           ret = RS2::C6;
 
1244
       } else if (p=="c7") {
 
1245
           ret = RS2::C7;
 
1246
       } else if (p=="c8") {
 
1247
           ret = RS2::C8;
 
1248
       } else if (p=="c9") {
 
1249
           ret = RS2::C9;
 
1250
       } else if (p=="c10") {
 
1251
           ret = RS2::C10;
 
1252
       }*/
 
1253
    else if (p=="c5e") {
 
1254
        ret = RS2::C5E;
 
1255
    } else if (p=="comm10e") {
 
1256
        ret = RS2::Comm10E;
 
1257
    } else if (p=="dle") {
 
1258
        ret = RS2::DLE;
 
1259
    } else if (p=="folio") {
 
1260
        ret = RS2::Folio;
 
1261
    //} else if (p=="ledger") {
 
1262
    //    ret = RS2::Ledger;
 
1263
    } else if (p=="tabloid") {
 
1264
        ret = RS2::Tabloid;
 
1265
    }
 
1266
    if (p==QString("Arch A")) return RS2::Arch_A;
 
1267
    if (p==QString("Arch B")) return RS2::Arch_B;
 
1268
    if (p==QString("Arch C")) return RS2::Arch_C;
 
1269
    if (p==QString("Arch D")) return RS2::Arch_D;
 
1270
    if (p==QString("Arch E")) return RS2::Arch_E;
 
1271
    if (p==QString("Arch E1")) return RS2::Arch_E1;
 
1272
    if (p==QString("Arch E2")) return RS2::Arch_E2;
 
1273
    if (p==QString("Arch E3")) return RS2::Arch_E3;
 
1274
 
 
1275
    if (p=="npagesize") return RS2::NPageSize;
 
1276
 
 
1277
    return ret;
 
1278
}
 
1279
 
 
1280
/**
 
1281
  * Calculates a scaling factor from given dpi and units.
 
1282
  */
 
1283
double RS_Units::dpiToScale(double dpi, RS2::Unit unit) {
 
1284
    double scale = RS_Units::convert(1.0, RS2::Inch, unit) / dpi;
 
1285
    return scale;
 
1286
}
 
1287
 
 
1288
/**
 
1289
  * Calculates a dpi value from given scaling factor and units.
 
1290
  */
 
1291
double RS_Units::scaleToDpi(double scale, RS2::Unit unit) {
 
1292
    double dpi = RS_Units::convert(1.0, RS2::Inch, unit) / scale;
 
1293
    return dpi;
 
1294
}
 
1295
 
 
1296
/**
 
1297
 * Performs some testing for the math class.
 
1298
 */
 
1299
void RS_Units::test() {
 
1300
    QString s;
 
1301
    double v;
 
1302
 
 
1303
    /*
 
1304
       std::cout << "RS_Units::test: formatLinear (decimal):\n";
 
1305
       v = 0.1;
 
1306
       s = RS_Units::formatLinear(v, RS2::Millimeter, RS2::Decimal,
 
1307
                                 3, false);
 
1308
       std::cout << "s: " << s << "\n";
 
1309
       assert(s=="0.1");
 
1310
       v = 0.01;
 
1311
       s = RS_Units::formatLinear(v, RS2::Millimeter, RS2::Decimal,
 
1312
                                 3, false);
 
1313
       std::cout << "s: " << s << "\n";
 
1314
       assert(s=="0.01");
 
1315
       v = 0.001;
 
1316
       s = RS_Units::formatLinear(v, RS2::Millimeter, RS2::Decimal,
 
1317
                                 3, false);
 
1318
       std::cout << "s: " << s << "\n";
 
1319
       assert(s=="0.001");
 
1320
       v = 0.009;
 
1321
       s = RS_Units::formatLinear(v, RS2::Millimeter, RS2::Decimal,
 
1322
                                 2, false);
 
1323
       std::cout << "s: " << s << "\n";
 
1324
       assert(s=="0.01");
 
1325
       v = 0.005;
 
1326
       s = RS_Units::formatLinear(v, RS2::Millimeter, RS2::Decimal,
 
1327
                                 2, false);
 
1328
       std::cout << "s: " << s << "\n";
 
1329
       assert(s=="0.01");
 
1330
       v = 0.0049999;
 
1331
       s = RS_Units::formatLinear(v, RS2::Millimeter, RS2::Decimal,
 
1332
                                 2, false);
 
1333
       std::cout << "s: " << s << "\n";
 
1334
       assert(s=="0");
 
1335
 
 
1336
       v = 0.1;
 
1337
       s = RS_Units::formatLinear(v, RS2::Millimeter, RS2::Decimal,
 
1338
                                 4, true);
 
1339
       std::cout << "s: " << s << "\n";
 
1340
       assert(s=="0.1mm");
 
1341
 
 
1342
 
 
1343
       std::cout << "RS_Units::test: formatLinear (fractional):\n";
 
1344
       v = 1.2;
 
1345
       s = RS_Units::formatLinear(v, RS2::Inch, RS2::Fractional,
 
1346
                                 6, false);
 
1347
       std::cout << "s: " << s << "\n";
 
1348
       assert(s=="1 13/64");
 
1349
 
 
1350
       v = 1.2;
 
1351
       s = RS_Units::formatLinear(v, RS2::Inch, RS2::Fractional,
 
1352
                                 8, false);
 
1353
       std::cout << "s: " << s << "\n";
 
1354
       assert(s=="1 51/256");
 
1355
 
 
1356
       v = 0.2;
 
1357
       s = RS_Units::formatLinear(v, RS2::Inch, RS2::Fractional,
 
1358
                                 8, false);
 
1359
       std::cout << "s: " << s << "\n";
 
1360
       assert(s=="51/256");
 
1361
 
 
1362
       v = 4.5;
 
1363
       s = RS_Units::formatLinear(v, RS2::Inch, RS2::Fractional,
 
1364
                                 6, true);
 
1365
       std::cout << "s: " << s << "\n";
 
1366
       assert(s=="4 1/2");
 
1367
 
 
1368
       v = 0.001;
 
1369
       s = RS_Units::formatLinear(v, RS2::Inch, RS2::Fractional,
 
1370
                                 0, false);
 
1371
       std::cout << "s: " << s << "\n";
 
1372
       assert(s=="0");
 
1373
 
 
1374
       v = 0.01;
 
1375
       s = RS_Units::formatLinear(v, RS2::Inch, RS2::Fractional,
 
1376
                                 8, false);
 
1377
       std::cout << "s: " << s << "\n";
 
1378
       assert(s=="3/256");
 
1379
 
 
1380
       v = 0.0078125;
 
1381
       s = RS_Units::formatLinear(v, RS2::Inch, RS2::Fractional,
 
1382
                                 8, false);
 
1383
       std::cout << "s: " << s << "\n";
 
1384
       assert(s=="1/128");
 
1385
 
 
1386
       v = 0.001;
 
1387
       s = RS_Units::formatLinear(v, RS2::Inch, RS2::Fractional,
 
1388
                                 8, false);
 
1389
       std::cout << "s: " << s << "\n";
 
1390
       assert(s=="0");
 
1391
 
 
1392
       v = 9.9999;
 
1393
       s = RS_Units::formatLinear(v, RS2::Inch, RS2::Fractional,
 
1394
                                 6, false);
 
1395
       std::cout << "s: " << s << "\n";
 
1396
       assert(s=="10");
 
1397
    */
 
1398
 
 
1399
    for (v=11.9999; v<12.0001; v+=0.0000001) {
 
1400
        for (int prec=0; prec<=6; ++prec) {
 
1401
            s = RS_Units::formatLinear(v, RS2::Inch, RS2::Architectural,
 
1402
                                       prec, true);
 
1403
                        // RVT_PORT changed  << s to s.ascii()
 
1404
            std::cout << "prec: " << prec << " v: " << v << " s: " << s.toLatin1().data() << "\n";
 
1405
        }
 
1406
    }
 
1407
 
 
1408
    /*for (v=0.0; v<10.0; v+=0.001) {
 
1409
        s = RS_Units::formatLinear(v, RS2::Foot, RS2::Fractional,
 
1410
                                  1.0/128.0, true);
 
1411
        std::cout << "v: " << v << " s: " << s << "\n";
 
1412
}*/
 
1413
 
 
1414
    /*
 
1415
    std::cout << "RS_Units::test: formatLinear (scientific):\n";
 
1416
    v = 0.001;
 
1417
    s = RS_Units::formatLinear(v, RS2::Millimeter, RS2::Scientific,
 
1418
                              0.0001, false);
 
1419
    std::cout << "s: " << s << "\n";
 
1420
    assert(s=="1.0e-3");
 
1421
    */
 
1422
 
 
1423
 
 
1424
    /*
 
1425
       std::cout << "RS_Units::test: formatAngle (deg / decimal):\n";
 
1426
       v = 0.0261799;
 
1427
       s = RS_Units::formatAngle(v, RS2::DegreesDecimal, 2);
 
1428
       std::cout << "s: " << s << "\n";
 
1429
       assert(s=="1.5∞");
 
1430
 
 
1431
       v = 0;
 
1432
       s = RS_Units::formatAngle(v, RS2::DegreesDecimal, 2);
 
1433
       std::cout << "s: " << s << "\n";
 
1434
       assert(s=="0∞");
 
1435
 
 
1436
       v = 1.5707963;
 
1437
       s = RS_Units::formatAngle(v, RS2::DegreesDecimal, 2);
 
1438
       std::cout << "s: " << s << "\n";
 
1439
       assert(s=="90∞");
 
1440
 
 
1441
       std::cout << "RS_Units::test: formatAngle (deg / d/m/s):\n";
 
1442
 
 
1443
       v = 0.0260926;
 
1444
       s = RS_Units::formatAngle(v, RS2::DegreesMinutesSeconds, 1);
 
1445
       std::cout << "s: " << s << "\n";
 
1446
       assert(s=="1∞ 29' 42\"");
 
1447
 
 
1448
       v = 0.0261799;
 
1449
       s = RS_Units::formatAngle(v, RS2::DegreesMinutesSeconds, 1);
 
1450
       std::cout << "s: " << s << "\n";
 
1451
       assert(s=="1∞ 30' 0\"");
 
1452
    */
 
1453
}
 
1454