diff options
| author | Andreas Grois <andreas.grois@jku.at> | 2015-11-06 13:45:57 +0100 |
|---|---|---|
| committer | Andreas Grois <andreas.grois@jku.at> | 2015-11-06 13:45:57 +0100 |
| commit | 4aa67d78e9238a65eb94a762328465e2541fd4c4 (patch) | |
| tree | 3711d160e87be100f8f31ba806a47b7efa600e56 | |
| parent | 05714900ad7c1638237749e88faae3ecdb19649e (diff) | |
Combine and sort results
This change introduces (experimental and not very clean) combining of results. It might be worth writing a disjoint angle range class to get cleaner code here, as the while loops at the end are quite far from being beautiful.
In addition the output ranges are sorted by their lower border. I'm using Lambda expressions for this, so C+11 is required.
Also, this is currently completely untested.
| -rw-r--r-- | CMakeLists.txt | 4 | ||||
| -rw-r--r-- | anglerange.cpp | 84 | ||||
| -rw-r--r-- | anglerange.h | 4 | ||||
| -rw-r--r-- | main.cpp | 83 |
4 files changed, 171 insertions, 4 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 5d66358..888ad9f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,8 +3,8 @@ cmake_minimum_required(VERSION 2.8) aux_source_directory(. SRC_LIST) add_executable(${PROJECT_NAME} ${SRC_LIST}) -SET(CMAKE_CXX_FLAGS "-Wall ${CMAKE_CXX_FLAGS}") -SET(CMAKE_CXX_FLAGS_DEBUG "-Wall ${CMAKE_CXX_FLAGS_DEBUG}") +SET(CMAKE_CXX_FLAGS "-Wall ${CMAKE_CXX_FLAGS} -std=c++11") +SET(CMAKE_CXX_FLAGS_DEBUG "-Wall ${CMAKE_CXX_FLAGS_DEBUG} -std=c++11") IF(UNIX) TARGET_LINK_LIBRARIES(${PROJECT_NAME} m) diff --git a/anglerange.cpp b/anglerange.cpp index f6b8264..7dda2e9 100644 --- a/anglerange.cpp +++ b/anglerange.cpp @@ -98,7 +98,7 @@ anglerange anglerange::overlap(const anglerange &other) //Here we need to take care to always follow the counter-clockwise convention. //This leaves us with four possibilities: //a) Both ranges contain the zero-line - //b) This range contains the zero-line, the other doesn'T + //b) This range contains the zero-line, the other doesn't //c) Vice versa //d) Both ranges are regular. @@ -170,3 +170,85 @@ anglerange anglerange::overlap(const anglerange &other) } return(retval); } + +anglerange anglerange::combine(const anglerange &other) +{ + anglerange retval; + //check if any of the ranges is empty. If yes: return an empty range as well. + if(!(isempty()) && !(other.isempty())){ + //Here we need to take care to always follow the counter-clockwise convention. + //This leaves us with four possibilities: + //a) Both ranges contain the zero-line + //b) This range contains the zero-line, the other doesn't + //c) Vice versa + //d) Both ranges are regular. + + //first check if this range contains the zero-line + if(lowerborder>upperborder) + { + //ok, this range is around zero. Let's check the other one too: + if(other.getlower()>other.getupper()) + { + //ok, both ranges contain the zero-line. + retval.setlower(fmin(lowerborder.getval(),other.getlower().getval())); + retval.setupper(fmax(upperborder.getval(),other.getupper().getval())); + } + else + { + //this contains zero, other doesn't. + //This cannot fully lie within other, but other can lie fully within this. + //The result does obviously contain zero. + //Let's check if other is within this. + if(other.getupper()<=upperborder || other.getlower()>=lowerborder){ + retval.setlower(lowerborder); + retval.setupper(upperborder); + } + else if(other.getupper()>=lowerborder) //not >, as per definition upperborder is inside range + { + retval.setlower(other.getlower()); + retval.setupper(upperborder); + } + else if(other.getlower()<=upperborder) //not <, as again upperborder is inside. + { + retval.setlower(lowerborder); + retval.setupper(other.getupper()); + } + } + } + else + { + //this is regular, is other as well? + if(other.getlower()>other.getupper()) + { + //so, other cannot lie in this, but this can be in other. + //Let's check for that. + if(upperborder<=other.getupper() || lowerborder>=other.getlower()){ + retval.setlower(other.getlower()); + retval.setupper(other.getupper()); + } + else if(lowerborder <= other.getupper()) + { + retval.setlower(other.getlower()); + retval.setupper(upperborder); + } + else if(upperborder >= other.getlower()) + { + retval.setlower(lowerborder); + retval.setupper(other.getupper()); + } + } + else //both ranges regular + { + //check if there's an overlap + double curmax = fmin(other.getupper().getval(),upperborder.getval()); + double curmin = fmax(other.getlower().getval(),lowerborder.getval()); + if(curmax>=curmin){ + //there is an overlap - set limits + retval.setlower(fmin(other.getlower().getval(),lowerborder.getval())); + retval.setupper(fmax(other.getupper().getval(),upperborder.getval())); + } + } + } + } + return(retval); +} diff --git a/anglerange.h b/anglerange.h index 4598e80..ab98cbc 100644 --- a/anglerange.h +++ b/anglerange.h @@ -62,6 +62,10 @@ public: //a new anglerange. anglerange overlap(const anglerange &other); + //this function does the opposite of overlap: Both ranges are combined into one bigger range. + //if they are disjoint, an empty range is given back. + anglerange combine(const anglerange &other); + }; #endif // ANGLERANGE_H @@ -67,6 +67,7 @@ #include <vector> #include <cmath> #include <cstdio> +#include <algorithm> #include "anglerange.h" using namespace std; @@ -352,7 +353,7 @@ int main(int argc, char* argv[]) } } } - +/* cout << "Possible coincident lattice matches with px, qx:" << std::endl; for(i=0;i<xoverlaps.size();i++) { @@ -363,6 +364,86 @@ int main(int argc, char* argv[]) { cout << (yoverlaps.at(i)).getlower().getval()*180/M_PI << " " << (yoverlaps.at(i)).getupper().getval()*180/M_PI << std::endl; } +*/ + //to make the output more readable, combine the ranges. + //first: copy xranges and yranges together: + std::vector<anglerange> ranges; + ranges.reserve(xoverlaps.size()+yoverlaps.size()+1); + ranges.insert(ranges.end(),xoverlaps.begin(),xoverlaps.end()); + ranges.insert(ranges.end(),yoverlaps.begin(),yoverlaps.end()); + if(ranges.size()>1) //combining elements only makes sense, if there are at least 2 elements to combine... + { + bool stop; + do + { + i=0; + stop=false; + do + { + j=i+1; + do + { + anglerange tmp = ranges.at(i).combine(ranges.at(j)); + if(!(tmp.isempty())) + { + stop=true; + ranges.push_back(tmp); + ranges.erase(ranges.begin()+j); + ranges.erase(ranges.begin()+i); + } + j++; + } + while(!stop && j<ranges.size()); + i++; + } + while(!stop && i<ranges.size()-1); //the -1 is there, as for i=ranges.size() there is no valid j any more. + } + while(stop); //yes, here is stop, not !stop, as stop means: stop to iterate over elements, go back to main loop, which should only terminate, if the internal loops finished. + } + + //the same thing for commensurate... + if(commensurate.size()>1) + { + bool stop; + do + { + i=0; + stop=false; + do + { + j=i+1; + do + { + anglerange tmp = commensurate.at(i).combine(commensurate.at(j)); + if(!(tmp.isempty())) + { + stop=true; + commensurate.push_back(tmp); + commensurate.erase(commensurate.begin()+j); + commensurate.erase(commensurate.begin()+i); + } + j++; + } + while(!stop && j<commensurate.size()); + i++; + } + while(!stop && i<commensurate.size()-1); //the -1 is there, as for i=commensurate.size() there is no valid j any more. + } + while(stop); //yes, here is stop, not !stop, as stop means: stop to iterate over elements, go back to main loop, which should only terminate, if the internal loops finished. + } + + //again,for readability: sort the ranges by their lower limit: + { + std::sort(ranges.begin(),ranges.end(),[](const anglerange &a,const anglerange &b){return(a.getlower()<b.getlower());}); + std::sort(commensurate.begin(),commensurate.end(),[](const anglerange &a,const anglerange &b){return(a.getlower()<b.getlower());}); + } + + + cout << "Possible coincident lattice matches:" << std::endl; + for(i=0;i<ranges.size();i++) + { + cout << (ranges.at(i)).getlower().getval()*180/M_PI << " " << (ranges.at(i)).getupper().getval()*180/M_PI << std::endl; + } cout << "Possible commensurate lattice matches:" << std::endl; for(i=0;i<commensurate.size();i++) { |
