Panda3D
distanceUnit.cxx
1 // Filename: distanceUnit.cxx
2 // Created by: drose (17Apr01)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #include "distanceUnit.h"
16 #include "config_pandatoolbase.h"
17 #include "string_utils.h"
18 #include "pnotify.h"
19 
20 ////////////////////////////////////////////////////////////////////
21 // Function: format_abbrev_unit
22 // Description: Returns the string representing the common
23 // abbreviation for the given unit.
24 ////////////////////////////////////////////////////////////////////
25 string
26 format_abbrev_unit(DistanceUnit unit) {
27  switch (unit) {
28  case DU_millimeters:
29  return "mm";
30 
31  case DU_centimeters:
32  return "cm";
33 
34  case DU_meters:
35  return "m";
36 
37  case DU_kilometers:
38  return "km";
39 
40  case DU_yards:
41  return "yd";
42 
43  case DU_feet:
44  return "ft";
45 
46  case DU_inches:
47  return "in";
48 
49  case DU_nautical_miles:
50  return "nmi";
51 
52  case DU_statute_miles:
53  return "mi";
54 
55  case DU_invalid:
56  return "invalid";
57  }
58  nout << "**unexpected DistanceUnit value: (" << (int)unit << ")**";
59  return "**";
60 }
61 
62 ////////////////////////////////////////////////////////////////////
63 // Function: format_long_unit
64 // Description: Returns the string representing the full name (plural)
65 // for the given unit.
66 ////////////////////////////////////////////////////////////////////
67 string
68 format_long_unit(DistanceUnit unit) {
69  switch (unit) {
70  case DU_millimeters:
71  return "millimeters";
72 
73  case DU_centimeters:
74  return "centimeters";
75 
76  case DU_meters:
77  return "meters";
78 
79  case DU_kilometers:
80  return "kilometers";
81 
82  case DU_yards:
83  return "yards";
84 
85  case DU_feet:
86  return "feet";
87 
88  case DU_inches:
89  return "inches";
90 
91  case DU_nautical_miles:
92  return "nautical miles";
93 
94  case DU_statute_miles:
95  return "miles";
96 
97  case DU_invalid:
98  return "invalid";
99  }
100  nout << "**unexpected DistanceUnit value: (" << (int)unit << ")**";
101  return "**";
102 }
103 
104 ////////////////////////////////////////////////////////////////////
105 // Function: DistanceUnit output operator
106 // Description:
107 ////////////////////////////////////////////////////////////////////
108 ostream &
109 operator << (ostream &out, DistanceUnit unit) {
110  return out << format_abbrev_unit(unit);
111 }
112 
113 ////////////////////////////////////////////////////////////////////
114 // Function: DistanceUnit input operator
115 // Description:
116 ////////////////////////////////////////////////////////////////////
117 istream &
118 operator >> (istream &in, DistanceUnit &unit) {
119  string word;
120  in >> word;
121  unit = string_distance_unit(word);
122  if (unit == DU_invalid) {
123  pandatoolbase_cat->error()
124  << "Invalid distance unit: " << word << "\n";
125  }
126  return in;
127 }
128 
129 ////////////////////////////////////////////////////////////////////
130 // Function: string_distance_unit
131 // Description: Converts from a string, as might be input by the
132 // user, to one of the known DistanceUnit types.
133 // Returns DU_invalid if the string is unknown.
134 ////////////////////////////////////////////////////////////////////
135 DistanceUnit
136 string_distance_unit(const string &str) {
137  if (cmp_nocase(str, "mm") == 0 || cmp_nocase(str, "millimeters") == 0) {
138  return DU_millimeters;
139 
140  } else if (cmp_nocase(str, "cm") == 0 || cmp_nocase(str, "centimeters") == 0) {
141  return DU_centimeters;
142 
143  } else if (cmp_nocase(str, "m") == 0 || cmp_nocase(str, "meters") == 0) {
144  return DU_meters;
145 
146  } else if (cmp_nocase(str, "km") == 0 || cmp_nocase(str, "kilometers") == 0) {
147  return DU_kilometers;
148 
149  } else if (cmp_nocase(str, "yd") == 0 || cmp_nocase(str, "yards") == 0) {
150  return DU_yards;
151 
152  } else if (cmp_nocase(str, "ft") == 0 || cmp_nocase(str, "feet") == 0) {
153  return DU_feet;
154 
155  } else if (cmp_nocase(str, "in") == 0 || cmp_nocase(str, "inches") == 0) {
156  return DU_inches;
157 
158  } else if (cmp_nocase(str, "nmi") == 0 ||
159  cmp_nocase(str, "nm") == 0 ||
160  cmp_nocase_uh(str, "nautical_miles") == 0) {
161  return DU_nautical_miles;
162 
163  } else if (cmp_nocase(str, "mi") == 0 ||
164  cmp_nocase(str, "miles") == 0 ||
165  cmp_nocase_uh(str, "statute_miles") == 0) {
166  return DU_statute_miles;
167 
168  } else {
169  return DU_invalid;
170  }
171 }
172 
173 ////////////////////////////////////////////////////////////////////
174 // Function: unit_scale
175 // Description: Returns the number of the indicated unit per each
176 // centimeter. This internal function is used to
177 // implement convert_units(), below.
178 ////////////////////////////////////////////////////////////////////
179 static double unit_scale(DistanceUnit unit) {
180  switch (unit) {
181  case DU_millimeters:
182  return 0.1;
183 
184  case DU_centimeters:
185  return 1.0;
186 
187  case DU_meters:
188  return 100.0;
189 
190  case DU_kilometers:
191  return 100000.0;
192 
193  case DU_yards:
194  return 3.0 * 12.0 * 2.54;
195 
196  case DU_feet:
197  return 12.0 * 2.54;
198 
199  case DU_inches:
200  return 2.54;
201 
202  case DU_nautical_miles:
203  // This is the U.S. definition.
204  return 185200.0;
205 
206  case DU_statute_miles:
207  return 5280.0 * 12.0 * 2.54;
208 
209  case DU_invalid:
210  return 1.0;
211  }
212 
213  return 1.0;
214 }
215 
216 ////////////////////////////////////////////////////////////////////
217 // Function: convert_units
218 // Description: Returns the scaling factor that must be applied to
219 // convert from units of "from" to "to".
220 ////////////////////////////////////////////////////////////////////
221 double convert_units(DistanceUnit from, DistanceUnit to) {
222  return unit_scale(from) / unit_scale(to);
223 }
224