Changeset 0d5ca7 for src/Fragmentation/Exporters
- Timestamp:
- Aug 20, 2014, 1:04:08 PM (11 years ago)
- Children:
- e139180
- Parents:
- 90426a
- git-author:
- Frederik Heber <heber@…> (06/02/14 14:51:33)
- git-committer:
- Frederik Heber <heber@…> (08/20/14 13:04:08)
- Location:
- src/Fragmentation/Exporters
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Fragmentation/Exporters/SphericalPointDistribution.cpp
r90426a r0d5ca7 44 44 #include <algorithm> 45 45 #include <cmath> 46 #include <functional> 47 #include <iterator> 46 48 #include <limits> 47 49 #include <list> … … 81 83 int current; 82 84 c_unique() {current=0;} 83 int operator()() {return ++current;}85 int operator()() {return current++;} 84 86 } UniqueNumber; 85 87 … … 125 127 } 126 128 } else 127 ELOG( 2, "calculateErrorOfMatching() - Given matching is empty.");129 ELOG(3, "calculateErrorOfMatching() - Given matching's size is less than 2."); 128 130 LOG(3, "INFO: Resulting errors for matching (L1, L2): " 129 131 << errors.first << "," << errors.second << "."); … … 156 158 } 157 159 158 /** Rotates a given polygon around x, y, and z axis by the given angles.159 *160 * Essentially, we concentrate on the three points of the polygon to rotate161 * to the correct position. First, we rotate its center via \a angles,162 * then we rotate the "triangle" around itself/\a _RotationAxis by163 * \a _RotationAngle.164 *165 * \param _polygon polygon whose points to rotate166 * \param _angles vector with rotation angles for x,y,z axis167 * \param _RotationAxis168 * \param _RotationAngle169 */170 SphericalPointDistribution::Polygon_t rotatePolygon(171 const SphericalPointDistribution::Polygon_t &_polygon,172 const std::vector<double> &_angles,173 const Line &_RotationAxis,174 const double _RotationAngle)175 {176 SphericalPointDistribution::Polygon_t rotated_polygon = _polygon;177 RealSpaceMatrix rotation;178 ASSERT( _angles.size() == 3,179 "rotatePolygon() - not exactly "+toString(3)+" angles given.");180 rotation.setRotation(_angles[0] * M_PI/180., _angles[1] * M_PI/180., _angles[2] * M_PI/180.);181 LOG(4, "DEBUG: Rotation matrix is " << rotation);182 183 // apply rotation angles184 for (SphericalPointDistribution::Polygon_t::iterator iter = rotated_polygon.begin();185 iter != rotated_polygon.end(); ++iter) {186 *iter = rotation * (*iter);187 _RotationAxis.rotateVector(*iter, _RotationAngle);188 }189 190 return rotated_polygon;191 }192 193 160 struct MatchingControlStructure { 194 161 bool foundflag; … … 214 181 LOG(4, "DEBUG: Recursing with current matching " << _matching 215 182 << ", remaining indices " << _indices 216 << ", and sought size " << _matching size);183 << ", and sought size " << _matching.size()+_matchingsize); 217 184 //!> threshold for L1 error below which matching is immediately acceptable 218 185 const double L1THRESHOLD = 1e-2; 219 186 if (!_MCS.foundflag) { 220 LOG( 3, "INFO: Current matching has size " << _matching.size() << " of" << _matchingsize);221 if (_matching .size() < _matchingsize) {187 LOG(4, "DEBUG: Current matching has size " << _matching.size() << ", places left " << _matchingsize); 188 if (_matchingsize > 0) { 222 189 // go through all indices 223 190 for (IndexList_t::iterator iter = _indices.begin(); 224 iter != _indices.end();) {191 (iter != _indices.end()) && (!_MCS.foundflag);) { 225 192 // add index to matching 226 193 _matching.push_back(*iter); 227 LOG( 4, "DEBUG: Adding " << *iter << " to matching.");194 LOG(5, "DEBUG: Adding " << *iter << " to matching."); 228 195 // remove index but keep iterator to position (is the next to erase element) 229 196 IndexList_t::iterator backupiter = _indices.erase(iter); … … 237 204 } 238 205 // gone through all indices then exit recursion 239 _MCS.foundflag = true; 206 if (_matching.empty()) 207 _MCS.foundflag = true; 240 208 } else { 241 209 LOG(3, "INFO: Found matching " << _matching); … … 246 214 _MCS.bestmatching = _matching; 247 215 _MCS.foundflag = true; 248 } 249 if (_MCS.bestL2 > errors.second) { 216 } else if (_MCS.bestL2 > errors.second) { 250 217 _MCS.bestmatching = _matching; 251 218 _MCS.bestL2 = errors.second; … … 254 221 } 255 222 } 223 224 /** Convert cartesian to polar coordinates. 225 * 226 * \param _cartesian vector in cartesian coordinates 227 * \return vector containing \f$ (r,\theta, \varphi \f$ tuple for polar coordinates 228 */ 229 std::vector<double> getPolarCoordinates(const Vector &_cartesian) 230 { 231 std::vector<double> polar(3,0.); 232 const double xsqr = _cartesian[0] * _cartesian[0]; 233 const double ysqr = _cartesian[1] * _cartesian[1]; 234 polar[0] = sqrt(xsqr + ysqr + _cartesian[2]*_cartesian[2]); 235 if (fabs(_cartesian[2]) < std::numeric_limits<double>::epsilon()*1e4) { 236 if (fabs(xsqr + ysqr) < std::numeric_limits<double>::epsilon()*1e4) { 237 polar[1] = 0.; 238 } else { 239 // xsqr + ysqr is always non-negative 240 polar[1] = M_PI/2.; 241 } 242 } else { 243 polar[1] = atan( sqrt(xsqr + ysqr)/_cartesian[2]); 244 if (_cartesian[2] <= -std::numeric_limits<double>::epsilon()*1e4) 245 polar[1] += M_PI; 246 } 247 248 if (fabs(_cartesian[0]) < std::numeric_limits<double>::epsilon()*1e4) { 249 if (fabs(_cartesian[1]) < std::numeric_limits<double>::epsilon()*1e4) { 250 polar[2] = 0.; 251 } else if (_cartesian[1] > std::numeric_limits<double>::epsilon()*1e4) { 252 polar[2] = M_PI/2.; 253 } else { 254 polar[2] = -M_PI/2.; 255 } 256 } else { 257 polar[2] = atan ( _cartesian[1]/_cartesian[0] ); 258 if (_cartesian[0] <= -std::numeric_limits<double>::epsilon()*1e4) 259 polar[2] += M_PI; 260 } 261 return polar; 262 } 263 264 /** Calculate cartesian coordinates from given polar ones. 265 * 266 * \param _polar vector with polar coordinates 267 * \return cartesian coordinates 268 */ 269 Vector getCartesianCoordinates(const std::vector<double> &_polar) 270 { 271 Vector cartesian; 272 ASSERT( _polar.size() == 3, 273 "convertToCartesianCoordinates() - tuples has insufficient components."); 274 cartesian[0] = _polar[0] * sin(_polar[1]) * cos(_polar[2]); 275 cartesian[1] = _polar[0] * sin(_polar[1]) * sin(_polar[2]); 276 cartesian[2] = _polar[0] * cos(_polar[1]); 277 return cartesian; 278 } 279 280 /** Rotates a given polygon around x, y, and z axis by the given angles. 281 * 282 * \param _polygon polygon whose points to rotate 283 * \param _angles vector with rotation angles for x,y,z axis 284 */ 285 SphericalPointDistribution::Polygon_t rotatePolygon( 286 const SphericalPointDistribution::Polygon_t &_polygon, 287 const std::vector<double> &_angles) 288 { 289 SphericalPointDistribution::Polygon_t rotated_polygon = _polygon; 290 RealSpaceMatrix rotation; 291 ASSERT( _angles.size() == 3, 292 "rotatePolygon() - not exactly "+toString(3)+" components given."); 293 294 // apply rotation angles 295 for (SphericalPointDistribution::Polygon_t::iterator iter = rotated_polygon.begin(); 296 iter != rotated_polygon.end(); ++iter) { 297 // transform to polar 298 std::vector<double> polar = getPolarCoordinates(*iter); 299 LOG(5, "DEBUG: Converting " << *iter << " to " << polar); 300 // sum up difference 301 std::transform( 302 _angles.begin(), _angles.end(), 303 polar.begin(), 304 polar.begin(), 305 std::plus<double>()); 306 // convert back 307 *iter = getCartesianCoordinates(polar); 308 LOG(5, "DEBUG: Converting modified " << polar << " to " << *iter); 309 } 310 311 return rotated_polygon; 312 } 313 256 314 257 315 SphericalPointDistribution::Polygon_t … … 264 322 VectorArray_t remainingold(_polygon.begin(), _polygon.end()); 265 323 VectorArray_t remainingnew(_newpolygon.begin(), _newpolygon.end()); 266 LOG( 3, "INFO: Matching old polygon " << _polygon324 LOG(2, "INFO: Matching old polygon " << _polygon 267 325 << " with new polygon " << _newpolygon); 268 326 … … 287 345 recurseMatchings(MCS, matching, indices, matchingsize); 288 346 } 289 LOG( 3, "INFO: Best matching is " << MCS.bestmatching);347 LOG(2, "INFO: Best matching is " << MCS.bestmatching); 290 348 291 349 // determine rotation angles to align the two point distributions with 292 350 // respect to bestmatching 293 std::vector<double> angles( 3);351 std::vector<double> angles(NDIM); 294 352 Vector newCenter; 353 Vector oldCenter; 295 354 { 296 355 // calculate center of triangle/line/point consisting of first points of matching 297 Vector oldCenter;298 356 IndexList_t::const_iterator iter = MCS.bestmatching.begin(); 299 357 unsigned int i = 0; … … 304 362 oldCenter *= 1./(double)i; 305 363 newCenter *= 1./(double)i; 306 LOG(3, "INFO: oldCenter is " << oldCenter << ", newCenter is " << newCenter); 307 308 Vector direction(0.,0.,0.); 309 for(size_t i=0;i<NDIM;++i) { 310 // create new rotation axis 311 direction[i] = 1.; 312 const Line axis (zeroVec, direction); 313 // calculate rotation angle for this axis 314 const double alpha = direction.Angle(oldCenter) - direction.Angle(newCenter); 315 // perform rotation 316 axis.rotateVector(newCenter, alpha); 317 // store angle 318 angles[i] = alpha; 319 // reset direction component for next iteration 320 direction[i] = 0.; 321 } 322 } 323 LOG(3, "INFO: (x,y,z) angles are" << angles); 324 const Line RotationAxis(zeroVec, newCenter); 325 const double RotationAngle = 326 newCenter.Angle(remainingold[0]) 327 - newCenter.Angle(remainingnew[*MCS.bestmatching.begin()]); 328 LOG(3, "INFO: Rotate around self is " << RotationAngle 329 << " around axis " << RotationAxis); 330 364 LOG(4, "DEBUG: oldCenter is " << oldCenter << ", newCenter is " << newCenter); 365 366 // transform to polar coordinates and note difference in angular parts 367 std::vector<double> oldpolar = getPolarCoordinates(oldCenter); 368 std::vector<double> newpolar = getPolarCoordinates(newCenter); 369 std::vector<double> differencepolar; 370 std::transform( 371 oldpolar.begin(), oldpolar.end(), 372 newpolar.begin(), 373 std::back_inserter(differencepolar), 374 std::minus<double>()); 375 LOG(3, "INFO: (r,theta,phi) angles are" << differencepolar); 376 } 331 377 // rotate _newpolygon 332 378 SphericalPointDistribution::Polygon_t rotated_newpolygon = 333 rotatePolygon(_newpolygon, angles, RotationAxis, RotationAngle); 334 LOG(3, "INFO: Rotated new polygon is " << rotated_newpolygon); 379 rotatePolygon(_newpolygon, angles); 380 LOG(5, "DEBUG: Rotated new polygon is " << rotated_newpolygon); 381 382 const Line RotationAxis(zeroVec, oldCenter); 383 const double RotationAngle = 384 oldCenter.Angle(remainingold[0]) 385 - oldCenter.Angle(remainingnew[*MCS.bestmatching.begin()]); 386 LOG(5, "DEBUG: Rotate around self is " << RotationAngle 387 << " around axis " << RotationAxis); 388 389 for (SphericalPointDistribution::Polygon_t::iterator iter = rotated_newpolygon.begin(); 390 iter != rotated_newpolygon.end(); ++iter) { 391 RotationAxis.rotateVector(*iter, RotationAngle); 392 } 335 393 336 394 // remove all points in matching and return remaining ones 337 return removeMatchingPoints(rotated_newpolygon, MCS.bestmatching); 395 SphericalPointDistribution::Polygon_t remainingpoints = 396 removeMatchingPoints(rotated_newpolygon, MCS.bestmatching); 397 LOG(2, "INFO: Remaining points are " << remainingpoints); 398 return remainingpoints; 338 399 } else 339 400 return _newpolygon; -
src/Fragmentation/Exporters/unittests/Makefile.am
r90426a r0d5ca7 18 18 19 19 TESTS += $(FRAGMENTATIONEXPORTERSTESTS) 20 XFAIL_TESTS += SphericalPointDistributionUnitTest21 20 check_PROGRAMS += $(FRAGMENTATIONEXPORTERSTESTS) 22 21 noinst_PROGRAMS += $(FRAGMENTATIONEXPORTERSTESTS)
Note:
See TracChangeset
for help on using the changeset viewer.