source: src/LinearAlgebra/LineSegmentSet.cpp@ 56f73b

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 56f73b was ad011c, checked in by Frederik Heber <heber@…>, 14 years ago

CodePatterns places all includes now in subfolder CodePatterns/.

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