00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include "geometry_3d.h"
00036
00037 #include <math.h>
00038
00039 #include "util/parsing.h"
00040 #include "util/token_stream.h"
00041
00042
00043
00044
00045
00046
00047
00048
00049 static void
00050 getDictionaryFromLine
00051 (
00052 IO std::istream& stream,
00053 IN const char * debug_info,
00054 OUT dictionary_t& d
00055 )
00056 {
00057 ASSERT(stream.good(), "bad?");
00058 ASSERT(debug_info, "null");
00059
00060 eParseBehavior behavior = (eParseBehavior)
00061 (eParse_StripComments | eParse_StripBogus);
00062
00063 std::string line = getNextLineFromStream(stream, behavior);
00064
00065 getDictionaryFromString(line.c_str(), debug_info, d);
00066 }
00067
00068
00069
00070 static float
00071 getOptionalFloat
00072 (
00073 IN const dictionary_t& d,
00074 IN const char * key
00075 )
00076 {
00077 ASSERT(key, "null");
00078
00079 return atof(getOptionalValue(d, key, "0"));
00080 }
00081
00082
00083
00084 void
00085 parsePointFromDictionary
00086 (
00087 IN const dictionary_t& d,
00088 OUT point3d_t& p
00089 )
00090 {
00091 p.x = getOptionalFloat(d, "x");
00092 p.y = getOptionalFloat(d, "y");
00093 p.z = getOptionalFloat(d, "z");
00094 }
00095
00096
00097
00098 void
00099 parseRectFromDictionary
00100 (
00101 IN const dictionary_t& d,
00102 OUT rect3d_t& rect
00103 )
00104 {
00105 rect.x0 = getOptionalFloat(d, "x0");
00106 rect.x1 = getOptionalFloat(d, "x1");
00107 rect.y0 = getOptionalFloat(d, "y0");
00108 rect.y1 = getOptionalFloat(d, "y1");
00109 rect.z0 = getOptionalFloat(d, "z0");
00110 rect.z1 = getOptionalFloat(d, "z1");
00111 }
00112
00113
00114
00115
00116
00117
00118
00119
00120 point3d_t
00121 rect3d_t::getCorner
00122 (
00123 IN int index
00124 )
00125 const
00126 throw()
00127 {
00128 ASSERT(index >= 0 && index < eMaxCorners,
00129 "Bad rectangle corner index: %d", index);
00130
00131 point3d_t retval;
00132 retval.x = (index % 2) ? x0 : x1;
00133 index /= 2;
00134 retval.y = (index % 2) ? y0 : y1;
00135 index /= 2;
00136 retval.z = (index % 2) ? z0 : z1;
00137
00138 return retval;
00139 }
00140
00141
00142
00143 void
00144 rect3d_t::getEdge
00145 (
00146 IN int index,
00147 OUT point3d_t& p0,
00148 OUT point3d_t& p1
00149 )
00150 const
00151 throw()
00152 {
00153 switch (index) {
00154 case 0:
00155 p0 = this->getCorner(0);
00156 p1 = this->getCorner(1);
00157 return;
00158
00159 case 1:
00160 p0 = this->getCorner(0);
00161 p1 = this->getCorner(2);
00162 return;
00163
00164 case 2:
00165 p0 = this->getCorner(0);
00166 p1 = this->getCorner(4);
00167 return;
00168
00169 case 3:
00170 p0 = this->getCorner(1);
00171 p1 = this->getCorner(3);
00172 return;
00173
00174 case 4:
00175 p0 = this->getCorner(1);
00176 p1 = this->getCorner(5);
00177 return;
00178
00179 case 5:
00180 p0 = this->getCorner(2);
00181 p1 = this->getCorner(3);
00182 return;
00183
00184 case 6:
00185 p0 = this->getCorner(2);
00186 p1 = this->getCorner(6);
00187 return;
00188
00189 case 7:
00190 p0 = this->getCorner(3);
00191 p1 = this->getCorner(7);
00192 return;
00193
00194 case 8:
00195 p0 = this->getCorner(4);
00196 p1 = this->getCorner(5);
00197 return;
00198
00199 case 9:
00200 p0 = this->getCorner(4);
00201 p1 = this->getCorner(6);
00202 return;
00203
00204 case 10:
00205 p0 = this->getCorner(5);
00206 p1 = this->getCorner(7);
00207 return;
00208
00209 case 11:
00210 p0 = this->getCorner(6);
00211 p1 = this->getCorner(7);
00212 return;
00213 }
00214
00215 ASSERT(index >= 0 && index <= eMaxEdges,
00216 "Bad rectangle edge index: %d", index);
00217 ASSERT(false, "should never get here");
00218 }
00219
00220
00221
00222 point3d_t
00223 operator *
00224 (
00225 IN const point3d_t& p,
00226 IN float r
00227 )
00228 throw()
00229 {
00230 point3d_t x = p;
00231 x.scale(r);
00232 return x;
00233 }
00234
00235
00236
00237 const vector3d_t&
00238 normalize
00239 (
00240 IO vector3d_t& v
00241 )
00242 throw()
00243 {
00244 float sum = v.x * v.x + v.y * v.y + v.z * v.z;
00245 if (0 == sum)
00246 return v;
00247
00248 sum = 1.0 / sqrt(sum);
00249 v.x *= sum;
00250 v.y *= sum;
00251 v.z *= sum;
00252
00253 return v;
00254 }
00255
00256
00257
00258 point3d_t
00259 readPoint
00260 (
00261 IN std::istream& stream
00262 )
00263 {
00264 point3d_t p;
00265 std::string token;
00266
00267 expectToken(stream, "{");
00268 expectToken(stream, "x");
00269 p.x = readFloat(stream, token);
00270 expectToken(stream, "y");
00271 p.y = readFloat(stream, token);
00272 expectToken(stream, "z");
00273 p.z = readFloat(stream, token);
00274 expectToken(stream, "}");
00275
00276 return p;
00277 }
00278
00279
00280
00281 rect3d_t
00282 readRect
00283 (
00284 IN std::istream& stream
00285 )
00286 {
00287 rect3d_t r;
00288 std::string token;
00289
00290 expectToken(stream, "{");
00291 expectToken(stream, "x0");
00292 r.x0 = readFloat(stream, token);
00293 expectToken(stream, "x1");
00294 r.x1 = readFloat(stream, token);
00295 expectToken(stream, "y0");
00296 r.y0 = readFloat(stream, token);
00297 expectToken(stream, "y1");
00298 r.y1 = readFloat(stream, token);
00299 expectToken(stream, "z0");
00300 r.z0 = readFloat(stream, token);
00301 expectToken(stream, "z1");
00302 r.z1 = readFloat(stream, token);
00303 expectToken(stream, "}");
00304
00305 return r;
00306 }
00307
00308
00309
00310 void
00311 parsePoint3d
00312 (
00313 IO std::istream& stream,
00314 OUT point3d_t& p
00315 )
00316 {
00317 ASSERT(stream.good(), "bad?");
00318
00319 dictionary_t d;
00320 getDictionaryFromLine(stream, "3D point", d);
00321
00322
00323
00324
00325 parsePointFromDictionary(d, p);
00326 }
00327
00328
00329
00330 void
00331 parseRect3d
00332 (
00333 IO std::istream& stream,
00334 OUT rect3d_t& rect
00335 )
00336 {
00337 ASSERT(stream.good(), "bad?");
00338
00339 dictionary_t d;
00340 getDictionaryFromLine(stream, "3D rectangle", d);
00341 parseRectFromDictionary(d, rect);
00342 }
00343
00344
00345
00346 void
00347 parsePoint3d
00348 (
00349 IN const char * string,
00350 OUT point3d_t& p
00351 )
00352 {
00353 ASSERT(string, "null");
00354
00355 dictionary_t d;
00356 getDictionaryFromString(string, "3D point", d);
00357 parsePointFromDictionary(d, p);
00358 }
00359
00360
00361
00362 void
00363 parseRect3d
00364 (
00365 IN const char * string,
00366 OUT rect3d_t& r
00367 )
00368 {
00369 ASSERT(string, "null");
00370
00371 dictionary_t d;
00372 getDictionaryFromString(string, "3D rectangle", d);
00373 parseRectFromDictionary(d, r);
00374 }
00375