source: src/LinearAlgebra/LineSegmentSet.cpp@ c38826

Action_Thermostats Add_AtomRandomPerturbation Add_FitFragmentPartialChargesAction Add_RotateAroundBondAction Add_SelectAtomByNameAction Added_ParseSaveFragmentResults AddingActions_SaveParseParticleParameters Adding_Graph_to_ChangeBondActions Adding_MD_integration_tests Adding_ParticleName_to_Atom Adding_StructOpt_integration_tests AtomFragments Automaking_mpqc_open AutomationFragmentation_failures Candidate_v1.5.4 Candidate_v1.6.0 Candidate_v1.6.1 ChangeBugEmailaddress ChangingTestPorts ChemicalSpaceEvaluator CombiningParticlePotentialParsing Combining_Subpackages Debian_Package_split Debian_package_split_molecuildergui_only Disabling_MemDebug Docu_Python_wait EmpiricalPotential_contain_HomologyGraph EmpiricalPotential_contain_HomologyGraph_documentation Enable_parallel_make_install Enhance_userguide Enhanced_StructuralOptimization Enhanced_StructuralOptimization_continued Example_ManyWaysToTranslateAtom Exclude_Hydrogens_annealWithBondGraph FitPartialCharges_GlobalError Fix_BoundInBox_CenterInBox_MoleculeActions Fix_ChargeSampling_PBC Fix_ChronosMutex Fix_FitPartialCharges Fix_FitPotential_needs_atomicnumbers Fix_ForceAnnealing Fix_IndependentFragmentGrids Fix_ParseParticles Fix_ParseParticles_split_forward_backward_Actions Fix_PopActions Fix_QtFragmentList_sorted_selection Fix_Restrictedkeyset_FragmentMolecule Fix_StatusMsg Fix_StepWorldTime_single_argument Fix_Verbose_Codepatterns Fix_fitting_potentials Fixes ForceAnnealing_goodresults ForceAnnealing_oldresults ForceAnnealing_tocheck ForceAnnealing_with_BondGraph ForceAnnealing_with_BondGraph_continued ForceAnnealing_with_BondGraph_continued_betteresults ForceAnnealing_with_BondGraph_contraction-expansion FragmentAction_writes_AtomFragments FragmentMolecule_checks_bonddegrees GeometryObjects Gui_Fixes Gui_displays_atomic_force_velocity ImplicitCharges IndependentFragmentGrids IndependentFragmentGrids_IndividualZeroInstances IndependentFragmentGrids_IntegrationTest IndependentFragmentGrids_Sole_NN_Calculation JobMarket_RobustOnKillsSegFaults JobMarket_StableWorkerPool JobMarket_unresolvable_hostname_fix MoreRobust_FragmentAutomation ODR_violation_mpqc_open PartialCharges_OrthogonalSummation PdbParser_setsAtomName PythonUI_with_named_parameters QtGui_reactivate_TimeChanged_changes Recreated_GuiChecks Rewrite_FitPartialCharges RotateToPrincipalAxisSystem_UndoRedo SaturateAtoms_findBestMatching SaturateAtoms_singleDegree StoppableMakroAction Subpackage_CodePatterns Subpackage_JobMarket Subpackage_LinearAlgebra Subpackage_levmar Subpackage_mpqc_open Subpackage_vmg Switchable_LogView ThirdParty_MPQC_rebuilt_buildsystem TrajectoryDependenant_MaxOrder TremoloParser_IncreasedPrecision TremoloParser_MultipleTimesteps TremoloParser_setsAtomName Ubuntu_1604_changes stable
Last change on this file since c38826 was 6c438f, checked in by Frederik Heber <heber@…>, 14 years ago

Merge branch 'StructureRefactoring' into Shapes

Conflicts:

src/Box.cpp
src/Box.hpp
src/Descriptors/AtomShapeDescriptor.cpp
src/Descriptors/AtomShapeDescriptor.hpp
src/Descriptors/AtomShapeDescriptor_impl.hpp
src/LinearAlgebra/Line.cpp
src/LinearAlgebra/Line.hpp
src/LinearAlgebra/Matrix.cpp
src/LinearAlgebra/Matrix.hpp
src/Makefile.am
src/Shapes/BaseShapes.cpp
src/Shapes/BaseShapes_impl.hpp
src/Shapes/Shape.cpp
src/Shapes/Shape.hpp
src/Shapes/ShapeOps_impl.hpp
src/Shapes/Shape_impl.hpp
src/unittests/ShapeUnittest.cpp

  • Property mode set to 100644
File size: 7.3 KB
Line 
1/*
2 * LineSegmentSet.cpp
3 *
4 * Created on: Jul 22, 2010
5 * Author: crueger
6 */
7
8#include "LinearAlgebra/LineSegmentSet.hpp"
9
10#include "Helpers/Assert.hpp"
11#include "LinearAlgebra/Line.hpp"
12#include "LinearAlgebra/LineSegment.hpp"
13
14#include "Helpers/Range.hpp"
15
16#include <algorithm>
17#include <boost/bind.hpp>
18
19using namespace std;
20
21LineSegmentSet::LineSegmentSet(const Line &_line) :
22 line(new Line(_line))
23{}
24
25LineSegmentSet::LineSegmentSet(const LineSegmentSet &src)
26{
27 line.reset(new Line(*src.line));
28 segments=src.segments;
29}
30
31LineSegmentSet& LineSegmentSet::operator=(const LineSegmentSet &src){
32 if(this!=&src){
33 lineptr _line(new Line(*src.line));
34 segments=src.segments;
35 line = _line;
36 }
37 return *this;
38}
39
40void LineSegmentSet::insert(const LineSegment &lineSeg){
41 ASSERT(*line==lineSeg.getLine(),"Inserted LineSegment was not from the line of the set");
42 // we might get messed up sets
43 if(lineSeg.hasZeroLength()){
44 // nothing to do here... there is practically nothing that is being inserted
45 return;
46 }
47 if(lineSeg.getBegin()>lineSeg.getEnd()){
48 // just insert the reversed set
49 insert(LineSegment(lineSeg.getEnd(),lineSeg.getBegin()));
50 return;
51 }
52 // get the first overlapping segment
53 set_t::iterator begin = find_if(segments.begin(),
54 segments.end(),
55 boost::bind(&LineSegment::overlaps,lineSeg,_1));
56 // see if we have overlapping segments
57 if(begin==segments.end()){
58 // no overlapping segments... we can just insert and get going
59 segments.insert(lineSeg);
60 return;
61 }
62 // get the last overlapping segment
63 set_t::iterator last = begin;
64 while(last!=segments.end() && lineSeg.overlaps(*last))++last;
65 last--;
66 // all segments between last and end now overlap and both are valid iterators
67 ASSERT(begin!=segments.end() && last!=segments.end(),"ERROR: last or begin are behind end of set");
68 // get the endpoints of the section
69 LinePoint beginPoint = min(begin->getBegin(),lineSeg.getBegin());
70 LinePoint endPoint = max(last->getEnd(),lineSeg.getEnd());
71 LineSegment insertSeg(beginPoint,endPoint);
72 // delete all overlapping segments
73 last++;
74 segments.erase(begin,last);
75 // insert the new combined segments
76 segments.insert(insertSeg);
77}
78
79void LineSegmentSet::erase(const LineSegment &lineSeg){
80 ASSERT(*line==lineSeg.getLine(),"Erased LineSegment was not from the line of the set");
81 // we might get messed up sets
82 if(lineSeg.hasZeroLength()){
83 // nothing to do here... there is practically nothing that is being erase
84 return;
85 }
86 if(lineSeg.getBegin()>lineSeg.getEnd()){
87 // just erase the reversed set
88 erase(LineSegment(lineSeg.getEnd(),lineSeg.getBegin()));
89 return;
90 }
91 // get the first overlapping segment
92 set_t::iterator begin = find_if(segments.begin(),
93 segments.end(),
94 boost::bind(&LineSegment::overlaps,lineSeg,_1));
95 if(begin==segments.end()){
96 // nothing to erase
97 return;
98 }
99 // get the last overlapping segment
100 set_t::iterator last = begin;
101 while(last!=segments.end() && lineSeg.overlaps(*last))++last;
102 last--;
103 // at the ends there might be two overlapping lineSegments of which parts remain
104 LineSegment beginSegment(begin->getBegin(),lineSeg.getBegin());
105 LineSegment endSegment(lineSeg.getEnd(),last->getEnd());
106 // erase all elements that have been overlapped
107 last++;
108 segments.erase(begin,last);
109 // insert the two segments if they still have space left
110 if(beginSegment.getBegin()<beginSegment.getEnd())
111 segments.insert(beginSegment);
112 if(endSegment.getBegin()<endSegment.getEnd())
113 segments.insert(endSegment);
114}
115
116LineSegmentSet::iterator LineSegmentSet::begin(){
117 return segments.begin();
118}
119LineSegmentSet::const_iterator LineSegmentSet::begin() const{
120 return segments.begin();
121}
122LineSegmentSet::iterator LineSegmentSet::end(){
123 return segments.end();
124}
125LineSegmentSet::const_iterator LineSegmentSet::end() const{
126 return segments.end();
127}
128
129bool LineSegmentSet::isContained(const Vector &point) const{
130 if(!line->isContained(point)){
131 return false;
132 }
133 LinePoint lp = line->getLinePoint(point);
134 for(set_t::iterator iter=segments.begin();iter!=segments.end();++iter){
135 if(iter->isContained(point)){
136 return true;
137 }
138 if(iter->getBegin()>lp){
139 break;
140 }
141 }
142 return false;
143}
144
145Line LineSegmentSet::getLine(){
146 return *line;
147}
148
149LineSegmentSet merge(const LineSegmentSet &x,const LineSegmentSet &y){
150 typedef range<LineSegmentSet::set_t::iterator> itRange;
151 ASSERT(*x.line==*y.line,"Lines of merges LineSegmentSets don't match");
152 LineSegmentSet res(*x.line);
153 // standard merge algorithm with a few modifications to deal with overlapping lines
154 itRange small(x.segments.begin(),x.segments.end());
155 itRange large(y.segments.begin(),y.segments.end());
156 while(small.first!=small.last && large.first != large.last){
157 if(large.first->getBegin()<small.first->getBegin()){
158 itRange tmp = small;
159 small = large;
160 large = tmp;
161 }
162
163 if(small.first->overlaps(*large.first)){
164 // get all overlapping segments from larger part
165 LineSegmentSet::set_t::iterator last = large.first;
166 while(last!=large.last && small.first->overlaps(*last))++last;
167 last--;
168 // get the endpoint of the new segment to be inserted
169 LinePoint lpEnd = max(small.first->getEnd(),last->getEnd());
170 res.segments.insert(LineSegment(small.first->getBegin(),lpEnd));
171 large.first=last; ++large.first; // all overlapping segments of the larger part have been dealt with
172 }
173 else{
174 // no overlap, we can just insert
175 res.segments.insert(*small.first);
176 }
177 ++small.first;
178 }
179 // deal with the rest of the iterator
180 // we don't know which one is done, so we just do both
181 res.segments.insert(small.first,small.last);
182 res.segments.insert(large.first,large.last);
183 return res;
184}
185
186LineSegmentSet intersect(const LineSegmentSet &x, const LineSegmentSet &y){
187 typedef range<LineSegmentSet::set_t::iterator> itRange;
188 ASSERT(*x.line==*y.line,"Lines of merges LineSegmentSets don't match");
189 LineSegmentSet res(*x.line);
190 itRange small(x.segments.begin(),x.segments.end());
191 itRange large(y.segments.begin(),y.segments.end());
192
193 while(small.first!=small.last && large.first != large.last){
194 if(large.first->getBegin()<small.first->getBegin()){
195 itRange tmp = small;
196 small = large;
197 large = tmp;
198 }
199 // add overlapping parts of segments from large
200 while(large.first!=large.last && small.first->overlaps(*large.first)){
201 LinePoint lpEnd = min(small.first->getEnd(),large.first->getEnd());
202 res.segments.insert(LineSegment(large.first->getBegin(),lpEnd));
203 ++large.first;
204 }
205 ++small.first;
206 }
207 return res;
208}
209
210LineSegmentSet invert(const LineSegmentSet &x){
211 LineSegmentSet res(*x.line);
212 LinePoint lpBegin = x.line->negEndpoint();
213 for(LineSegmentSet::set_t::iterator iter = x.segments.begin();iter!=x.segments.end();++iter){
214 if(lpBegin!=iter->getBegin())
215 res.segments.insert(LineSegment(lpBegin,iter->getBegin()));
216 // the end of the current scanned segment is the beginning of the next one to insert
217 lpBegin = iter->getEnd();
218 }
219 // we might need to extend to infinity
220 if(!lpBegin.isPosInfinity())
221 res.segments.insert(LineSegment(lpBegin,x.line->posEndpoint()));
222 return res;
223}
Note: See TracBrowser for help on using the repository browser.