- Timestamp:
- Aug 20, 2014, 1:06:16 PM (11 years ago)
- Children:
- f5fa48
- Parents:
- c8d2e7
- git-author:
- Frederik Heber <heber@…> (07/18/14 16:24:53)
- git-committer:
- Frederik Heber <heber@…> (08/20/14 13:06:16)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Fragmentation/Exporters/SphericalPointDistribution.cpp
rc8d2e7 rce0ca4 1022 1022 } 1023 1023 1024 1024 SphericalPointDistribution::PolygonWithIndexTuples 1025 SphericalPointDistribution::getAssociatedPoints( 1026 const WeightedPolygon_t &_polygon, 1027 const int _N) 1028 { 1029 SphericalPointDistribution::PolygonWithIndexTuples associatedpoints; 1030 1031 // initialze to given number of points 1032 initSelf(_N); 1033 LOG(2, "INFO: Matching old polygon " << _polygon 1034 << " with new polygon " << points); 1035 1036 // check whether there are any points to associate 1037 if (_polygon.empty()) { 1038 associatedpoints.polygon.insert( 1039 associatedpoints.polygon.end(), 1040 points.begin(), points.end()); 1041 return associatedpoints; 1042 } 1043 1044 if (_N > 0) { 1045 // combine multiple points and create simple IndexList from IndexTupleList 1046 MatchingControlStructure MCS = findBestMatching(_polygon); 1047 IndexList_t bestmatching = joinPoints(points, MCS.newpoints, MCS.bestmatching); 1048 LOG(2, "INFO: Best matching is " << bestmatching); 1049 1050 // gather the associated points (not the joined ones) 1051 associatedpoints.polygon = MCS.newpoints; 1052 // gather indices 1053 associatedpoints.indices = MCS.bestmatching; 1054 1055 /// now we only need to rotate the associated points to match the given ones 1056 /// with respect to the joined points in points 1057 1058 const size_t NumberIds = std::min(bestmatching.size(), (size_t)3); 1059 // create old set 1060 PolygonWithIndices oldSet; 1061 oldSet.indices.resize(NumberIds, -1); 1062 std::generate(oldSet.indices.begin(), oldSet.indices.end(), UniqueNumber); 1063 for (WeightedPolygon_t::const_iterator iter = _polygon.begin(); 1064 iter != _polygon.end(); ++iter) 1065 oldSet.polygon.push_back(iter->first); 1066 1067 // _newpolygon has changed, so now convert to array with matched indices 1068 PolygonWithIndices newSet; 1069 SphericalPointDistribution::IndexList_t::const_iterator beginiter = bestmatching.begin(); 1070 SphericalPointDistribution::IndexList_t::const_iterator enditer = bestmatching.begin(); 1071 std::advance(enditer, NumberIds); 1072 newSet.indices.resize(NumberIds, -1); 1073 std::copy(beginiter, enditer, newSet.indices.begin()); 1074 std::copy(points.begin(),points.end(), std::back_inserter(newSet.polygon)); 1075 1076 // determine rotation angles to align the two point distributions with 1077 // respect to bestmatching: 1078 // we use the center between the three first matching points 1079 /// the first rotation brings these two centers to coincide 1080 PolygonWithIndices rotatednewSet = newSet; 1081 { 1082 Rotation_t Rotation = findPlaneAligningRotation(oldSet, newSet); 1083 LOG(5, "DEBUG: Rotating coordinate system by " << Rotation.second 1084 << " around axis " << Rotation.first); 1085 Line Axis(zeroVec, Rotation.first); 1086 1087 // apply rotation angle to bring newCenter to oldCenter in joined points 1088 for (VectorArray_t::iterator iter = rotatednewSet.polygon.begin(); 1089 iter != rotatednewSet.polygon.end(); ++iter) { 1090 Vector ¤t = *iter; 1091 LOG(6, "DEBUG: Original joined point is " << current); 1092 current = Axis.rotateVector(current, Rotation.second); 1093 LOG(6, "DEBUG: Rotated joined point is " << current); 1094 } 1095 1096 // apply rotation angle to the whole set of associated points 1097 for (VectorArray_t::iterator iter = associatedpoints.polygon.begin(); 1098 iter != associatedpoints.polygon.end(); ++iter) { 1099 Vector ¤t = *iter; 1100 LOG(6, "DEBUG: Original associated point is " << current); 1101 current = Axis.rotateVector(current, Rotation.second); 1102 LOG(6, "DEBUG: Rotated associated point is " << current); 1103 } 1104 1105 #ifndef NDEBUG 1106 // check: rotated "newCenter" should now equal oldCenter 1107 // we don't check in case of two points as these lie on a great circle 1108 // and the center cannot stably be recalculated. We may reactivate this 1109 // when we calculate centers only once 1110 if (oldSet.indices.size() > 2) { 1111 Vector oldCenter; 1112 Vector rotatednewCenter; 1113 calculateOldAndNewCenters( 1114 oldCenter, rotatednewCenter, 1115 oldSet, rotatednewSet); 1116 oldCenter.Normalize(); 1117 rotatednewCenter.Normalize(); 1118 // check whether centers are anti-parallel (factor -1) 1119 // then we have the "non-unique poles" situation: points lie on great circle 1120 // and both poles are valid solution 1121 if (fabs(oldCenter.ScalarProduct(rotatednewCenter) + 1.) 1122 < std::numeric_limits<double>::epsilon()*1e4) 1123 rotatednewCenter *= -1.; 1124 LOG(4, "CHECK: rotatednewCenter is " << rotatednewCenter 1125 << ", oldCenter is " << oldCenter); 1126 const double difference = (rotatednewCenter - oldCenter).NormSquared(); 1127 ASSERT( difference < std::numeric_limits<double>::epsilon()*1e4, 1128 "matchSphericalPointDistributions() - rotation does not work as expected by " 1129 +toString(difference)+"."); 1130 } 1131 #endif 1132 } 1133 /// the second (orientation) rotation aligns the planes such that the 1134 /// points themselves coincide 1135 if (bestmatching.size() > 1) { 1136 Rotation_t Rotation = findPointAligningRotation(oldSet, rotatednewSet); 1137 1138 // construct RotationAxis and two points on its plane, defining the angle 1139 Rotation.first.Normalize(); 1140 const Line RotationAxis(zeroVec, Rotation.first); 1141 1142 LOG(5, "DEBUG: Rotating around self is " << Rotation.second 1143 << " around axis " << RotationAxis); 1144 1145 #ifndef NDEBUG 1146 // check: first bestmatching in rotated_newpolygon and remainingnew 1147 // should now equal 1148 { 1149 const IndexList_t::const_iterator iter = bestmatching.begin(); 1150 1151 // check whether both old and newPosition are at same distance to oldCenter 1152 Vector oldCenter = calculateCenter(oldSet); 1153 const double distance = fabs( 1154 (oldSet.polygon[0] - oldCenter).NormSquared() 1155 - (rotatednewSet.polygon[*iter] - oldCenter).NormSquared() 1156 ); 1157 LOG(4, "CHECK: Squared distance between oldPosition and newPosition " 1158 << " with respect to oldCenter " << oldCenter << " is " << distance); 1159 // ASSERT( distance < warn_amplitude, 1160 // "matchSphericalPointDistributions() - old and newPosition's squared distance to oldCenter differs by " 1161 // +toString(distance)); 1162 1163 Vector rotatednew = RotationAxis.rotateVector( 1164 rotatednewSet.polygon[*iter], 1165 Rotation.second); 1166 LOG(4, "CHECK: rotated first new bestmatching is " << rotatednew 1167 << " while old was " << oldSet.polygon[0]); 1168 const double difference = (rotatednew - oldSet.polygon[0]).NormSquared(); 1169 ASSERT( difference < distance+1e-8, 1170 "matchSphericalPointDistributions() - orientation rotation ends up off by " 1171 +toString(difference)+", more than " 1172 +toString(distance+1e-8)+"."); 1173 } 1174 #endif 1175 1176 // align the set of associated points only here 1177 for (VectorArray_t::iterator iter = associatedpoints.polygon.begin(); 1178 iter != associatedpoints.polygon.end(); ++iter) { 1179 Vector ¤t = *iter; 1180 LOG(6, "DEBUG: Original associated point is " << current); 1181 current = RotationAxis.rotateVector(current, Rotation.second); 1182 LOG(6, "DEBUG: Rotated associated point is " << current); 1183 } 1184 } 1185 } 1186 1187 return associatedpoints; 1188 } 1189 1190 SphericalPointDistribution::PolygonWithIndexTuples 1191 SphericalPointDistribution::getIdentityAssociation( 1192 const WeightedPolygon_t &_polygon) 1193 { 1194 unsigned int index = 0; 1195 SphericalPointDistribution::PolygonWithIndexTuples returnpolygon; 1196 for (WeightedPolygon_t::const_iterator iter = _polygon.begin(); 1197 iter != _polygon.end(); ++iter, ++index) { 1198 returnpolygon.polygon.push_back( iter->first ); 1199 ASSERT( iter->second == 1, 1200 "getIdentityAssociation() - bond with direction " 1201 +toString(iter->second) 1202 +" has degree higher than 1, getIdentityAssociation makes no sense."); 1203 returnpolygon.indices.push_back( IndexList_t(1, index) ); 1204 } 1205 return returnpolygon; 1206 }
Note:
See TracChangeset
for help on using the changeset viewer.
