Files
newspark110/lib/engine/rs_units.cpp
Chenwenxuan edac2715f0 init
2024-03-06 14:54:30 +08:00

1174 lines
32 KiB
C++

/****************************************************************************
**
** This file is part of the LibreCAD project, a 2D CAD program
**
** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
**
**
** This file may be distributed and/or modified under the terms of the
** GNU General Public License version 2 as published by the Free Software
** Foundation and appearing in the file gpl-2.0.txt included in the
** packaging of this file.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
**
** This copyright notice MUST APPEAR in all copies of the script!
**
**********************************************************************/
#include<iostream>
#include<cmath>
#include <QObject>
#include <QStringList>
#include "rs_units.h"
#include "rs_math.h"
#include "rs_vector.h"
#include "rs_debug.h"
/**
* Converts a DXF integer () to a Unit enum.
*/
RS2::Unit RS_Units::dxfint2unit(int dxfint) {
return (RS2::Unit)dxfint;
/*switch(dxfint) {
default:
case 0:
return RS2::None;
case 1:
return RS2::Inch;
case 2:
return RS2::Foot;
case 3:
return RS2::Mile;
case 4:
return RS2::Millimeter;
case 5:
return RS2::Centimeter;
case 6:
return RS2::Meter;
case 7:
return RS2::Kilometer;
case 8:
return RS2::Microinch;
case 9:
return RS2::Mil;
case 10:
return RS2::Yard;
case 11:
return RS2::Angstrom;
case 12:
return RS2::Nanometer;
case 13:
return RS2::Micron;
case 14:
return RS2::Decimeter;
case 15:
return RS2::Decameter;
case 16:
return RS2::Hectometer;
case 17:
return RS2::Gigameter;
case 18:
return RS2::Astro;
case 19:
return RS2::Lightyear;
case 20:
return RS2::Parsec;
}*/
}
/**
* @return a short string representing the given unit (e.g. "mm")
*/
QString RS_Units::unitToSign(RS2::Unit u) {
QString ret = "";
switch (u) {
case RS2::None:
ret = "";
break;
case RS2::Inch:
ret = "\"";
break;
case RS2::Foot:
ret = "'";
break;
case RS2::Mile:
ret = "mi";
break;
case RS2::Millimeter:
ret = "mm";
break;
case RS2::Centimeter:
ret = "cm";
break;
case RS2::Meter:
ret = "m";
break;
case RS2::Kilometer:
ret = "km";
break;
case RS2::Microinch:
ret = "µ\"";
break;
case RS2::Mil:
ret = "mil";
break;
case RS2::Yard:
ret = "yd";
break;
case RS2::Angstrom:
ret = "A";
break;
case RS2::Nanometer:
ret = "nm";
break;
case RS2::Micron:
ret = "µm";
break;
case RS2::Decimeter:
ret = "dm";
break;
case RS2::Decameter:
ret = "dam";
break;
case RS2::Hectometer:
ret = "hm";
break;
case RS2::Gigameter:
ret = "Gm";
break;
case RS2::Astro:
ret = "astro";
break;
case RS2::Lightyear:
ret = "ly";
break;
case RS2::Parsec:
ret = "pc";
break;
default:
ret = "";
break;
}
return ret;
}
/**
* @return a string representing the given unit (e.g. "Millimeter").
* translated if @a t is true (the default).
*/
QString RS_Units::unitToString(RS2::Unit u, bool t) {
switch (u) {
case RS2::None:
return t ? QObject::tr("None", "unknown length unit") : "None";
case RS2::Inch:
return t ? QObject::tr("Inch") : "Inch";
case RS2::Foot:
return t ? QObject::tr("Foot") : "Foot";
case RS2::Mile:
return t ? QObject::tr("Mile") : "Mile";
case RS2::Millimeter:
return t ? QObject::tr("Millimeter") : "Millimeter";
case RS2::Centimeter:
return t ? QObject::tr("Centimeter") : "Centimeter";
case RS2::Meter:
return t ? QObject::tr("Meter") : "Meter";
case RS2::Kilometer:
return t ? QObject::tr("Kilometer") : "Kilometer";
case RS2::Microinch:
return t ? QObject::tr("Microinch") : "Microinch";
case RS2::Mil:
return t ? QObject::tr("Mil") : "Mil";
case RS2::Yard:
return t ? QObject::tr("Yard") : "Yard";
case RS2::Angstrom:
return t ? QObject::tr("Angstrom") : "Angstrom";
case RS2::Nanometer:
return t ? QObject::tr("Nanometer") : "Nanometer";
case RS2::Micron:
return t ? QObject::tr("Micron") : "Micron";
case RS2::Decimeter:
return t ? QObject::tr("Decimeter") : "Decimeter";
case RS2::Decameter:
return t ? QObject::tr("Decameter") : "Decameter";
case RS2::Hectometer:
return t ? QObject::tr("Hectometer") : "Hectometer";
case RS2::Gigameter:
return t ? QObject::tr("Gigameter") : "Gigameter";
case RS2::Astro:
return t ? QObject::tr("Astro") : "Astro";
case RS2::Lightyear:
return t ? QObject::tr("Lightyear") : "Lightyear";
case RS2::Parsec:
return t ? QObject::tr("Parsec") : "Parsec";
default:
return "";
}
}
/**
* Converts a string into a unit enum.
*/
RS2::Unit RS_Units::stringToUnit(const QString& u) {
RS2::Unit ret = RS2::None;
if (u=="None") {
ret = RS2::None;
} else if (u==QObject::tr("Inch")) {
ret = RS2::Inch;
} else if (u==QObject::tr("Foot")) {
ret = RS2::Foot;
} else if (u==QObject::tr("Mile")) {
ret = RS2::Mile;
} else if (u==QObject::tr("Millimeter")) {
ret = RS2::Millimeter;
} else if (u==QObject::tr("Centimeter")) {
ret = RS2::Centimeter;
} else if (u==QObject::tr("Meter")) {
ret = RS2::Meter;
} else if (u==QObject::tr("Kilometer")) {
ret = RS2::Kilometer;
} else if (u==QObject::tr("Microinch")) {
ret = RS2::Microinch;
} else if (u==QObject::tr("Mil")) {
ret = RS2::Mil;
} else if (u==QObject::tr("Yard")) {
ret = RS2::Yard;
} else if (u==QObject::tr("Angstrom")) {
ret = RS2::Angstrom;
} else if (u==QObject::tr("Nanometer")) {
ret = RS2::Nanometer;
} else if (u==QObject::tr("Micron")) {
ret = RS2::Micron;
} else if (u==QObject::tr("Decimeter")) {
ret = RS2::Decimeter;
} else if (u==QObject::tr("Decameter")) {
ret = RS2::Decameter;
} else if (u==QObject::tr("Hectometer")) {
ret = RS2::Hectometer;
} else if (u==QObject::tr("Gigameter")) {
ret = RS2::Gigameter;
} else if (u==QObject::tr("Astro")) {
ret = RS2::Astro;
} else if (u==QObject::tr("Lightyear")) {
ret = RS2::Lightyear;
} else if (u==QObject::tr("Parsec")) {
ret = RS2::Parsec;
}
return ret;
}
/**
* @return true: the unit is metric, false: the unit is imperial.
*/
bool RS_Units::isMetric(RS2::Unit u) {
switch (u) {
case RS2::Millimeter:
case RS2::Centimeter:
case RS2::Meter:
case RS2::Kilometer:
case RS2::Angstrom:
case RS2::Nanometer:
case RS2::Micron:
case RS2::Decimeter:
case RS2::Decameter:
case RS2::Hectometer:
case RS2::Gigameter:
case RS2::Astro:
case RS2::Lightyear:
case RS2::Parsec:
return true;
default:
return false;
}
}
/**
* @return factor to convert the given unit to Millimeters.
*/
double RS_Units::getFactorToMM(RS2::Unit u) {
switch (u) {
default:
case RS2::None:
case RS2::Millimeter:
return 1.0;
case RS2::Inch:
return 25.4;
case RS2::Foot:
return 304.8;
case RS2::Mile:
return 1.609344e6; //international mile
case RS2::Centimeter:
return 10;
case RS2::Meter:
return 1e3;
case RS2::Kilometer:
return 1e6;
case RS2::Microinch:
return 2.54e-5;
case RS2::Mil:
return 0.0254;
case RS2::Yard:
return 914.4;
case RS2::Angstrom:
return 1e-7;
case RS2::Nanometer:
return 1e-6;
case RS2::Micron:
return 1e-3;
case RS2::Decimeter:
return 100.0;
case RS2::Decameter:
return 1e4;
case RS2::Hectometer:
return 1e5;
case RS2::Gigameter:
return 1e9;
case RS2::Astro:
return 1.495978707e14;
case RS2::Lightyear:
return 9.4607304725808e18;
case RS2::Parsec:
return 3.0856776e19;
}
}
/**
* Converts the given value 'val' from unit 'src' to unit 'dest'.
*/
double RS_Units::convert(double val, RS2::Unit src, RS2::Unit dest) {
if (getFactorToMM(dest)>0.0) {
return (val*getFactorToMM(src))/getFactorToMM(dest);
} else {
RS_DEBUG->print(RS_Debug::D_WARNING,
"RS_Units::convert: invalid factor");
return val;
}
}
/**
* Converts the given vector 'val' from unit 'src' to unit 'dest'.
*/
RS_Vector RS_Units::convert(const RS_Vector& val, RS2::Unit src, RS2::Unit dest) {
return RS_Vector(convert(val.x, src, dest),
convert(val.y, src, dest),
convert(val.z, src, dest)
);
}
/**
* Formats the given length in the given format.
*
* @param length The length in the current unit of the drawing.
* @param format Format of the string.
* @param prec Precision of the value (e.g. 0.001 or 1/128 = 0.0078125)
& @param showUnit Append unit to the value.
*/
QString RS_Units::formatLinear(double length, RS2::Unit unit,
RS2::LinearFormat format,
int prec, bool showUnit) {
QString ret;
// unit appended to value (e.g. 'mm'):
/*QString unitString = "";
if (showUnit) {
unitString = unitToSign(unit);
}*/
// barbarian display: show as fraction:
switch (format) {
case RS2::Scientific:
ret = formatScientific(length, unit, prec, showUnit);
break;
case RS2::Decimal:
ret = formatDecimal(length, unit, prec, showUnit);
break;
case RS2::Engineering:
ret = formatEngineering(length, unit, prec, showUnit);
break;
case RS2::Architectural:
ret = formatArchitectural(length, unit, prec, showUnit);
break;
case RS2::Fractional:
ret = formatFractional(length, unit, prec, showUnit);
break;
case RS2::ArchitecturalMetric:
ret = formatArchitecturalMetric(length, unit, prec, showUnit);
break;
default:
RS_DEBUG->print(RS_Debug::D_WARNING,
"RS_Units::formatLinear: Unknown format");
ret = "";
break;
}
return ret;
}
/**
* Formats the given length in scientific format (e.g. 2.5E7).
*
* @param length The length in the current unit of the drawing.
* @param prec Precision of the value (e.g. 0.001 or 1/128 = 0.0078125)
& @param showUnit Append unit to the value.
*/
QString RS_Units::formatScientific(double length, RS2::Unit unit,
int prec, bool showUnit) {
QString const ret= QString("%1").arg(length,0,'E', prec);
if(showUnit)
return ret + unitToSign(unit);
return ret;
}
/**
* Formats the given length in decimal (normal) format (e.g. 2.5).
*
* @param length The length in the current unit of the drawing.
* @param prec Precision of the value (e.g. 0.001)
& @param showUnit Append unit to the value.
*/
QString RS_Units::formatDecimal(double length, RS2::Unit unit,
int prec, bool showUnit) {
QString const ret=RS_Math::doubleToString(length, prec);
if(showUnit)
return ret+unitToSign(unit);
return ret;
}
/**
* Formats the given length in engineering format (e.g. 5' 4.5").
*
* @param length The length in the current unit of the drawing.
* @param prec Precision of the value (e.g. 0.001 or 1/128 = 0.0078125)
& @param showUnit Append unit to the value.
*/
QString RS_Units::formatEngineering(double length, RS2::Unit /*unit*/,
int prec, bool /*showUnit*/) {
QString ret;
bool sign = (length<0.0);
int feet = (int)floor(fabs(length)/12);
double inches = fabs(length) - feet*12;
QString sInches = RS_Math::doubleToString(inches, prec);
if (sInches=="12") {
feet++;
sInches="0";
}
if (feet) {
ret = QString("%1'-%2\"").arg(feet).arg(sInches);
} else {
ret = QString("%1\"").arg(sInches);
}
if (sign) {
ret = "-" + ret;
}
return ret;
}
/**
* Formats the given length in architectural format (e.g. 5' 4 1/2").
*
* @param length The length in the current unit of the drawing.
* @param prec Precision of the value (e.g. 0.001 or 1/128 = 0.0078125)
& @param showUnit Append unit to the value.
*/
QString RS_Units::formatArchitectural(double length, RS2::Unit /*unit*/,
int prec, bool showUnit) {
QString ret;
bool neg = (length<0.0);
int feet = (int)floor(fabs(length)/12);
double inches = fabs(length) - feet*12;
QString sInches = formatFractional(inches, RS2::Inch, prec, showUnit);
if (sInches=="12") {
feet++;
sInches = "0";
}
if (neg) {
ret = QString("-%1'-%2\"").arg(feet).arg(sInches);
} else {
ret = QString("%1'-%2\"").arg(feet).arg(sInches);
}
return ret;
}
/**
* Formats the given length in metric architectural format
* using DIN 406 (e.g. 1.12⁵).
*
* @param length The length in the current unit of the drawing.
* @param prec Precision of the value (e.g. 0.001)
& @param showUnit Append unit to the value.
*/
QString RS_Units::formatArchitecturalMetric(double length, RS2::Unit unit,
int prec, bool showUnit) {
QString ret;
bool neg = (length<0.0);
QString zero = "0";
if (neg)
length = length * -1.0;
ret = RS_Math::doubleToString(length, prec + 1);
int iLast = QString(ret.right(1)).toInt();
// round on 0.005 and use superscript 5
if ((iLast > 2) && (iLast < 8)) {
ret = ret.replace(ret.length() - 1, 1, "\u2075");
} else {
ret = RS_Math::doubleToString(length, prec);
}
// return values < 1.00m in cm (0.42 -> 42)
if (ret.startsWith(zero)) {
ret = ret.split(".")[1];
// eliminate leading zeros (0.07 -> 7)
if (ret.startsWith(zero)) {
ret = ret.remove(0, 1);
}
}
if (showUnit) {
ret = QString("%1 %2").arg(ret).arg(unitToSign(unit));
}
if (neg) {
ret = QString("-%1").arg(ret);
}
return ret;
}
/**
* Formats the given length in fractional (barbarian) format (e.g. 5' 3 1/64").
*
* @param length The length in the current unit of the drawing.
* @param unit Should be inches.
* @param prec Precision of the value (e.g. 0.001 or 1/128 = 0.0078125)
& @param showUnit Append unit to the value.
*/
QString RS_Units::formatFractional(double length, RS2::Unit /*unit*/,
int prec, bool /*showUnit*/) {
QString ret;
unsigned num; // number of complete inches (num' 7/128")
unsigned nominator; // number of fractions (nominator/128)
unsigned denominator; // (7/denominator)
// sign:
QString neg = "";
if(length < 0) {
neg = "-";
length = fabs(length);
}
num = (unsigned)floor(length);
denominator = 2<<prec;
nominator = (unsigned) RS_Math::round((length-num)*denominator);
// fraction rounds up to 1:
if (nominator==denominator) {
nominator=0;
denominator=0;
++num;
}
// Simplify the fraction
if (nominator && denominator) {
unsigned gcd = RS_Math::findGCD(nominator, denominator);
if (gcd) {
nominator = nominator / gcd;
denominator = denominator / gcd;
} else {
RS_DEBUG->print(RS_Debug::D_WARNING,
"RS_Units::formatFractional: invalid gcd");
nominator = 0;
denominator = 0;
}
}
if( num && nominator ) {
ret = QString("%1%2 %3/%4").arg(neg).arg(num).arg(nominator).arg(denominator);
} else if(nominator) {
ret = QString("%1%2/%3").arg(neg).arg(nominator).arg(denominator);
} else if(num) {
ret = QString("%1%2").arg(neg).arg(num);
} else {
ret = "0";
}
return ret;
}
/**
* Formats the given angle with the given format.
*
* @param angle The angle (always in rad).
* @param format Format of the string.
* @param prec Precision of the value (e.g. 0.001 or 1/128 = 0.0078125)
*
* @ret String with the formatted angle.
*/
QString RS_Units::formatAngle(double angle, RS2::AngleFormat format,
int prec) {
QString ret;
double value;
switch (format) {
case RS2::Surveyors:
case RS2::DegreesDecimal:
case RS2::DegreesMinutesSeconds:
value = RS_Math::rad2deg(angle);
break;
case RS2::Radians:
value = angle;
break;
case RS2::Gradians:
value = RS_Math::rad2gra(angle);
break;
default:
RS_DEBUG->print(RS_Debug::D_WARNING,
"RS_Units::formatAngle: Unknown Angle Unit");
return "";
break;
}
switch (format) {
case RS2::DegreesDecimal:
case RS2::Radians:
case RS2::Gradians:
ret = RS_Math::doubleToString(value, prec);
if (format==RS2::DegreesDecimal)
ret+=QChar(0xB0);
if (format==RS2::Radians)
ret+="r";
if (format==RS2::Gradians)
ret+="g";
break;
case RS2::DegreesMinutesSeconds: {
int vDegrees, vMinutes;
double vSeconds;
QString degrees, minutes, seconds;
vDegrees = (int)floor(value);
vMinutes = (int)floor((value - vDegrees) * 60.0);
vSeconds = (value - vDegrees - (vMinutes/60.0)) * 3600.0;
seconds = RS_Math::doubleToString(vSeconds, (prec>1 ? prec-2 : 0));
if(seconds=="60") {
seconds="0";
++vMinutes;
if(vMinutes==60) {
vMinutes=0;
++vDegrees;
}
}
if (prec==0 && vMinutes>=30.0) {
vDegrees++;
} else if (prec==1 && vSeconds>=30.0) {
vMinutes++;
}
degrees.setNum(vDegrees);
minutes.setNum(vMinutes);
switch (prec) {
case 0:
ret = degrees + QChar(0xB0);
break;
case 1:
ret = degrees + QChar(0xB0) + " " + minutes + "'";
break;
default:
ret = degrees + QChar(0xB0) + " " + minutes + "' "
+ seconds + "\"";
break;
}
}
break;
case RS2::Surveyors: {
QString prefix,suffix;
int quadrant;
quadrant = ((int)floor(value)/90);
switch(quadrant){
case 0:
prefix="N";
suffix="E";
break;
case 1:
prefix="S";
suffix="E";
value=180. - value;
break;
case 2:
prefix="S";
suffix="W";
value=value - 180.;
break;
case 3:
prefix="N";
suffix="W";
value=360. - value;
break;
}
ret = prefix+formatAngle(RS_Math::deg2rad(value),RS2::DegreesMinutesSeconds,prec)+suffix;
ret.replace(QChar(0xB0),"d");
ret.replace(" ","");
}
break;
default:
break;
}
return ret;
}
/**
* Converts the given number from a DXF file into an AngleFormat enum.
*
* @param num $DIMAUNIT from DXF (0: decimal deg, 1: deg/min/sec, 2: gradians,
* 3: radians, 4: surveyor's units)
*
* @ret Matching AngleFormat enum value.
*/
RS2::AngleFormat RS_Units::numberToAngleFormat(int num) {
RS2::AngleFormat af;
switch (num) {
default:
case 0:
af = RS2::DegreesDecimal;
break;
case 1:
af = RS2::DegreesMinutesSeconds;
break;
case 2:
af = RS2::Gradians;
break;
case 3:
af = RS2::Radians;
break;
case 4:
af = RS2::Surveyors;
break;
}
return af;
}
/**
* @return Size of the given paper format.
*/
RS_Vector RS_Units::paperFormatToSize(RS2::PaperFormat p) {
switch (p) {
case RS2::Custom:
return RS_Vector(0.0, 0.0);
case RS2::A0:
return RS_Vector(841.0, 1189.0);
case RS2::A1:
return RS_Vector(594.0, 841.0);
case RS2::A2:
return RS_Vector(420.0, 594.0);
case RS2::A3:
return RS_Vector(297.0, 420.0);
case RS2::A4:
return RS_Vector(210.0, 297.0);
/* Removed ISO "B" and "C" series, C5E, Comm10E, DLE, (envelope sizes) */
case RS2::Letter: /* 8.5 x 11.0 in. Sizes shown are used for 'hard' conversion to metric */
return RS_Vector(215.9, 279.4);
case RS2::Legal: /* 8.5 x 14.0 in */
return RS_Vector(215.9, 355.6);
case RS2::Tabloid: /* 11.0 x 17.0 */
return RS_Vector(279.4, 431.8);
//case RS2::Ansi_A: /* 8.5 x 11.0 in */
// return RS_Vector(215.9, 279.4);
//case RS2::Ansi_B: /* 11.0 x 17.0 in */
// return RS_Vector(279.4, 431.8);
case RS2::Ansi_C: /* 17.0 x 22.0 in */
return RS_Vector(431.8, 558.8);
case RS2::Ansi_D: /* 22.0 x 34.0 in */
return RS_Vector(558.8, 863.6);
case RS2::Ansi_E: /* 34.0 x 44.0 in */
return RS_Vector(863.6, 1117.6);
case RS2::Arch_A: /* 9.0 x 12.0 in */
return RS_Vector(228.6, 304.8);
case RS2::Arch_B: /* 12.0 x 18.0 in */
return RS_Vector(304.8, 457.2);
case RS2::Arch_C: /* 18.0 x 24.0 in */
return RS_Vector(457.2, 609.6);
case RS2::Arch_D: /* 24.0 x 36.0 in */
return RS_Vector(609.6, 914.4);
case RS2::Arch_E: /* 36.0 x 48.0 in */
return RS_Vector(914.4, 1219.2);
default:
break;
}
return RS_Vector (false);
}
/**
* Gets the paper format which matches the given size. If no
* format matches, RS2::Custom is returned.
*/
RS2::PaperFormat RS_Units::paperSizeToFormat(const RS_Vector& s) {
RS_Vector ts1;
RS_Vector ts2;
for (RS2::PaperFormat i = RS2::FirstPaperFormat; RS2::NPageFormat > i; i = static_cast<RS2::PaperFormat>(i + 1)) {
ts1 = RS_Units::paperFormatToSize(i);
ts2 = RS_Vector(ts1.y, ts1.x);
if (ts1.distanceTo(s) < 1.0e-4 || ts2.distanceTo(s) < 1.0e-4) {
return i;
}
}
return RS2::Custom;
}
/**
* Converts a paper format to a string (e.g. for a combobox).
*/
QString RS_Units::paperFormatToString(RS2::PaperFormat p) {
switch (p) {
case RS2::Custom: return QObject::tr( "Custom", "Paper format");
case RS2::A0: return QObject::tr( "A0", "Paper format");
case RS2::A1: return QObject::tr( "A1", "Paper format");
case RS2::A2: return QObject::tr( "A2", "Paper format");
case RS2::A3: return QObject::tr( "A3", "Paper format");
case RS2::A4: return QObject::tr( "A4", "Paper format");
/* Removed ISO "B" and "C" series, C5E, Comm10E, DLE, (envelope sizes) */
case RS2::Letter: return QObject::tr( "Letter / ANSI A", "Paper format");
case RS2::Legal: return QObject::tr( "Legal", "Paper format");
case RS2::Tabloid: return QObject::tr( "Tabloid / ANSI B", "Paper format");
//case RS2::Ansi_A: return QObject::tr( "Letter / ANSI A", "Paper format");
//case RS2::Ansi_B: return QObject::tr( "Tabloid / ANSI B", "Paper format");
case RS2::Ansi_C: return QObject::tr( "ANSI C", "Paper format");
case RS2::Ansi_D: return QObject::tr( "ANSI D", "Paper format");
case RS2::Ansi_E: return QObject::tr( "ANSI E", "Paper format");
case RS2::Arch_A: return QObject::tr( "Arch A", "Paper format");
case RS2::Arch_B: return QObject::tr( "Arch B", "Paper format");
case RS2::Arch_C: return QObject::tr( "Arch C", "Paper format");
case RS2::Arch_D: return QObject::tr( "Arch D", "Paper format");
case RS2::Arch_E: return QObject::tr( "Arch E", "Paper format");
default:
break;
}
return QStringLiteral("");
}
/**
* Converts a string to a paper format.
*/
RS2::PaperFormat RS_Units::stringToPaperFormat(const QString& p) {
QString ls {p.toLower()};
// use toLower() on localized paper format strings, don't trust that translators keep lower case
if (ls == QStringLiteral("custom") || ls == QObject::tr("custom", "Paper format").toLower())
return RS2::Custom;
if (ls == QStringLiteral("a0") || ls == QObject::tr("a0", "Paper format").toLower())
return RS2::A0;
if (ls == QStringLiteral("a1") || ls == QObject::tr("a1", "Paper format").toLower())
return RS2::A1;
if (ls == QStringLiteral("a2") || ls == QObject::tr("a2", "Paper format").toLower())
return RS2::A2;
if (ls == QStringLiteral("a3") || ls == QObject::tr("a3", "Paper format").toLower())
return RS2::A3;
if (ls == QStringLiteral("a4") || ls == QObject::tr("a4", "Paper format").toLower())
return RS2::A4;
/* Removed ISO "B" and "C" series, C5E, Comm10E, DLE, (envelope sizes) */
if (ls == QStringLiteral("letter") || ls == QObject::tr("letter", "Paper format").toLower())
return RS2::Letter;
if (ls == QStringLiteral("legal") || ls == QObject::tr("legal", "Paper format").toLower())
return RS2::Legal;
if (ls == QStringLiteral("tabloid") || ls == QObject::tr("tabloid", "Paper format").toLower())
return RS2::Tabloid;
//if (ls == QStringLiteral("ansi a") || ls == QObject::tr("ansi a", "Paper format").toLower())
// return RS2::Ansi_A;
//if (ls == QStringLiteral("ansi b") || ls == QObject::tr("ansi b", "Paper format").toLower())
// return RS2::Ansi_B;
if (ls == QStringLiteral("ansi c") || ls == QObject::tr("ansi c", "Paper format").toLower())
return RS2::Ansi_C;
if (ls == QStringLiteral("ansi d") || ls == QObject::tr("ansi d", "Paper format").toLower())
return RS2::Ansi_D;
if (ls == QStringLiteral("ansi e") || ls == QObject::tr("ansi e", "Paper format").toLower())
return RS2::Ansi_E;
if (ls == QStringLiteral("arch a") || ls == QObject::tr("arch a", "Paper format").toLower())
return RS2::Arch_A;
if (ls == QStringLiteral("arch b") || ls == QObject::tr("arch b", "Paper format").toLower())
return RS2::Arch_B;
if (ls == QStringLiteral("arch c") || ls == QObject::tr("arch c", "Paper format").toLower())
return RS2::Arch_C;
if (ls == QStringLiteral("arch d") || ls == QObject::tr("arch d", "Paper format").toLower())
return RS2::Arch_D;
if (ls == QStringLiteral("arch e") || ls == QObject::tr("arch e", "Paper format").toLower())
return RS2::Arch_E;
return RS2::Custom;
}
/**
* Calculates a scaling factor from given dpi and units.
*/
double RS_Units::dpiToScale(double dpi, RS2::Unit unit) {
double scale = RS_Units::convert(1.0, RS2::Inch, unit) / dpi;
return scale;
}
/**
* Calculates a dpi value from given scaling factor and units.
*/
double RS_Units::scaleToDpi(double scale, RS2::Unit unit) {
double dpi = RS_Units::convert(1.0, RS2::Inch, unit) / scale;
return dpi;
}
/**
* Performs some testing for the math class.
*/
void RS_Units::test() {
QString s;
double v;
/*
std::cout << "RS_Units::test: formatLinear (decimal):\n";
v = 0.1;
s = RS_Units::formatLinear(v, RS2::Millimeter, RS2::Decimal,
3, false);
std::cout << "s: " << s << "\n";
assert(s=="0.1");
v = 0.01;
s = RS_Units::formatLinear(v, RS2::Millimeter, RS2::Decimal,
3, false);
std::cout << "s: " << s << "\n";
assert(s=="0.01");
v = 0.001;
s = RS_Units::formatLinear(v, RS2::Millimeter, RS2::Decimal,
3, false);
std::cout << "s: " << s << "\n";
assert(s=="0.001");
v = 0.009;
s = RS_Units::formatLinear(v, RS2::Millimeter, RS2::Decimal,
2, false);
std::cout << "s: " << s << "\n";
assert(s=="0.01");
v = 0.005;
s = RS_Units::formatLinear(v, RS2::Millimeter, RS2::Decimal,
2, false);
std::cout << "s: " << s << "\n";
assert(s=="0.01");
v = 0.0049999;
s = RS_Units::formatLinear(v, RS2::Millimeter, RS2::Decimal,
2, false);
std::cout << "s: " << s << "\n";
assert(s=="0");
v = 0.1;
s = RS_Units::formatLinear(v, RS2::Millimeter, RS2::Decimal,
4, true);
std::cout << "s: " << s << "\n";
assert(s=="0.1mm");
std::cout << "RS_Units::test: formatLinear (fractional):\n";
v = 1.2;
s = RS_Units::formatLinear(v, RS2::Inch, RS2::Fractional,
6, false);
std::cout << "s: " << s << "\n";
assert(s=="1 13/64");
v = 1.2;
s = RS_Units::formatLinear(v, RS2::Inch, RS2::Fractional,
8, false);
std::cout << "s: " << s << "\n";
assert(s=="1 51/256");
v = 0.2;
s = RS_Units::formatLinear(v, RS2::Inch, RS2::Fractional,
8, false);
std::cout << "s: " << s << "\n";
assert(s=="51/256");
v = 4.5;
s = RS_Units::formatLinear(v, RS2::Inch, RS2::Fractional,
6, true);
std::cout << "s: " << s << "\n";
assert(s=="4 1/2");
v = 0.001;
s = RS_Units::formatLinear(v, RS2::Inch, RS2::Fractional,
0, false);
std::cout << "s: " << s << "\n";
assert(s=="0");
v = 0.01;
s = RS_Units::formatLinear(v, RS2::Inch, RS2::Fractional,
8, false);
std::cout << "s: " << s << "\n";
assert(s=="3/256");
v = 0.0078125;
s = RS_Units::formatLinear(v, RS2::Inch, RS2::Fractional,
8, false);
std::cout << "s: " << s << "\n";
assert(s=="1/128");
v = 0.001;
s = RS_Units::formatLinear(v, RS2::Inch, RS2::Fractional,
8, false);
std::cout << "s: " << s << "\n";
assert(s=="0");
v = 9.9999;
s = RS_Units::formatLinear(v, RS2::Inch, RS2::Fractional,
6, false);
std::cout << "s: " << s << "\n";
assert(s=="10");
*/
for (v=11.9999; v<12.0001; v+=0.0000001) {
for (int prec=0; prec<=6; ++prec) {
s = RS_Units::formatLinear(v, RS2::Inch, RS2::Architectural,
prec, true);
// RVT_PORT changed << s to s.ascii()
std::cout << "prec: " << prec << " v: " << v << " s: " << s.toLatin1().data() << "\n";
}
}
/*for (v=0.0; v<10.0; v+=0.001) {
s = RS_Units::formatLinear(v, RS2::Foot, RS2::Fractional,
1.0/128.0, true);
std::cout << "v: " << v << " s: " << s << "\n";
}*/
/*
std::cout << "RS_Units::test: formatLinear (scientific):\n";
v = 0.001;
s = RS_Units::formatLinear(v, RS2::Millimeter, RS2::Scientific,
0.0001, false);
std::cout << "s: " << s << "\n";
assert(s=="1.0e-3");
*/
/*
std::cout << "RS_Units::test: formatAngle (deg / decimal):\n";
v = 0.0261799;
s = RS_Units::formatAngle(v, RS2::DegreesDecimal, 2);
std::cout << "s: " << s << "\n";
assert(s=="1.5∞");
v = 0;
s = RS_Units::formatAngle(v, RS2::DegreesDecimal, 2);
std::cout << "s: " << s << "\n";
assert(s=="0∞");
v = 1.5707963;
s = RS_Units::formatAngle(v, RS2::DegreesDecimal, 2);
std::cout << "s: " << s << "\n";
assert(s=="90∞");
std::cout << "RS_Units::test: formatAngle (deg / d/m/s):\n";
v = 0.0260926;
s = RS_Units::formatAngle(v, RS2::DegreesMinutesSeconds, 1);
std::cout << "s: " << s << "\n";
assert(s=="1∞ 29' 42\"");
v = 0.0261799;
s = RS_Units::formatAngle(v, RS2::DegreesMinutesSeconds, 1);
std::cout << "s: " << s << "\n";
assert(s=="1∞ 30' 0\"");
*/
}