source: src/Shapes/Shape.cpp@ 2ad482

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 Candidate_v1.7.0 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 2ad482 was c6f395, checked in by Tillmann Crueger <crueger@…>, 15 years ago

Added methods to calculate the intersections of Shapes with arbitrary lines

  • Property mode set to 100644
File size: 6.6 KB
Line 
1/*
2 * Shape.cpp
3 *
4 * Created on: Jun 18, 2010
5 * Author: crueger
6 */
7
8#include "Shape.hpp"
9#include "Shape_impl.hpp"
10
11#include "Helpers/Assert.hpp"
12
13#include <string>
14
15using namespace std;
16
17Shape::Shape(const Shape& src) :
18 impl(src.getImpl())
19{}
20
21Shape::~Shape(){}
22
23bool Shape::isInside(const Vector &point) const{
24 return impl->isInside(point);
25}
26
27bool Shape::isOnSurface(const Vector &point) const{
28 return impl->isOnSurface(point);
29}
30
31Vector Shape::getNormal(const Vector &point) const throw (NotOnSurfaceException){
32 return impl->getNormal(point);
33}
34
35LineSegmentSet Shape::getLineIntersections(const Line &line){
36 return impl->getLineIntersections(line);
37}
38
39Shape::Shape(Shape::impl_ptr _impl) :
40 impl(_impl)
41{}
42
43Shape &Shape::operator=(const Shape& rhs){
44 if(&rhs!=this){
45 impl=rhs.getImpl();
46 }
47 return *this;
48}
49
50std::string Shape::toString() const{
51 return impl->toString();
52}
53
54Shape::impl_ptr Shape::getImpl() const{
55 return impl;
56}
57
58// allows arbitrary friendship, but only if implementation is known
59Shape::impl_ptr getShapeImpl(const Shape &shape){
60 return shape.getImpl();
61}
62
63/***************************** Some simple Shapes ***************************/
64
65Shape Everywhere(){
66 static Shape::impl_ptr impl = Shape::impl_ptr(new Everywhere_impl());
67 return Shape(impl);
68}
69
70Shape Nowhere(){
71 static Shape::impl_ptr impl = Shape::impl_ptr(new Nowhere_impl());
72 return Shape(impl);
73}
74
75/****************************** Operators ***********************************/
76
77// AND
78
79AndShape_impl::AndShape_impl(const Shape::impl_ptr &_lhs, const Shape::impl_ptr &_rhs) :
80 lhs(_lhs),rhs(_rhs)
81{}
82
83AndShape_impl::~AndShape_impl(){}
84
85bool AndShape_impl::isInside(const Vector &point){
86 return lhs->isInside(point) && rhs->isInside(point);
87}
88
89bool AndShape_impl::isOnSurface(const Vector &point){
90 // check the number of surfaces that this point is on
91 int surfaces =0;
92 surfaces += lhs->isOnSurface(point);
93 surfaces += rhs->isOnSurface(point);
94
95 switch(surfaces){
96 case 0:
97 return false;
98 // no break necessary
99 case 1:
100 // if it is inside for the object where it does not lie on
101 // the surface the whole point lies inside
102 return (lhs->isOnSurface(point) && rhs->isInside(point)) ||
103 (rhs->isOnSurface(point) && lhs->isInside(point));
104 // no break necessary
105 case 2:
106 {
107 // it lies on both Shapes... could be an edge or an inner point
108 // test the direction of the normals
109 Vector direction=lhs->getNormal(point)+rhs->getNormal(point);
110 // if the directions are opposite we lie on the inside
111 return !direction.IsZero();
112 }
113 // no break necessary
114 default:
115 // if this happens there is something wrong
116 ASSERT(0,"Default case should have never been used");
117 }
118 return false; // never reached
119}
120
121Vector AndShape_impl::getNormal(const Vector &point) throw (NotOnSurfaceException){
122 Vector res;
123 if(!isOnSurface(point)){
124 throw NotOnSurfaceException(__FILE__,__LINE__);
125 }
126 res += lhs->isOnSurface(point)?lhs->getNormal(point):zeroVec;
127 res += rhs->isOnSurface(point)?rhs->getNormal(point):zeroVec;
128 res.Normalize();
129 return res;
130}
131
132LineSegmentSet AndShape_impl::getLineIntersections(const Line &line){
133 return intersect(lhs->getLineIntersections(line),rhs->getLineIntersections(line));
134}
135
136string AndShape_impl::toString(){
137 return string("(") + lhs->toString() + string("&&") + rhs->toString() + string(")");
138}
139
140Shape operator&&(const Shape &lhs,const Shape &rhs){
141 Shape::impl_ptr newImpl = Shape::impl_ptr(new AndShape_impl(getShapeImpl(lhs),getShapeImpl(rhs)));
142 return Shape(newImpl);
143}
144
145// OR
146
147OrShape_impl::OrShape_impl(const Shape::impl_ptr &_lhs, const Shape::impl_ptr &_rhs) :
148 lhs(_lhs),rhs(_rhs)
149{}
150
151OrShape_impl::~OrShape_impl(){}
152
153bool OrShape_impl::isInside(const Vector &point){
154 return rhs->isInside(point) || lhs->isInside(point);
155}
156
157bool OrShape_impl::isOnSurface(const Vector &point){
158 // check the number of surfaces that this point is on
159 int surfaces =0;
160 surfaces += lhs->isOnSurface(point);
161 surfaces += rhs->isOnSurface(point);
162
163 switch(surfaces){
164 case 0:
165 return false;
166 // no break necessary
167 case 1:
168 // if it is inside for the object where it does not lie on
169 // the surface the whole point lies inside
170 return (lhs->isOnSurface(point) && !rhs->isInside(point)) ||
171 (rhs->isOnSurface(point) && !lhs->isInside(point));
172 // no break necessary
173 case 2:
174 {
175 // it lies on both Shapes... could be an edge or an inner point
176 // test the direction of the normals
177 Vector direction=lhs->getNormal(point)+rhs->getNormal(point);
178 // if the directions are opposite we lie on the inside
179 return !direction.IsZero();
180 }
181 // no break necessary
182 default:
183 // if this happens there is something wrong
184 ASSERT(0,"Default case should have never been used");
185 }
186 return false; // never reached
187}
188
189Vector OrShape_impl::getNormal(const Vector &point) throw (NotOnSurfaceException){
190 Vector res;
191 if(!isOnSurface(point)){
192 throw NotOnSurfaceException(__FILE__,__LINE__);
193 }
194 res += lhs->isOnSurface(point)?lhs->getNormal(point):zeroVec;
195 res += rhs->isOnSurface(point)?rhs->getNormal(point):zeroVec;
196 res.Normalize();
197 return res;
198}
199
200LineSegmentSet OrShape_impl::getLineIntersections(const Line &line){
201 return merge(lhs->getLineIntersections(line),rhs->getLineIntersections(line));
202}
203
204string OrShape_impl::toString(){
205 return string("(") + lhs->toString() + string("||") + rhs->toString() + string(")");
206}
207
208Shape operator||(const Shape &lhs,const Shape &rhs){
209 Shape::impl_ptr newImpl = Shape::impl_ptr(new OrShape_impl(getShapeImpl(lhs),getShapeImpl(rhs)));
210 return Shape(newImpl);
211}
212
213// NOT
214
215NotShape_impl::NotShape_impl(const Shape::impl_ptr &_arg) :
216 arg(_arg)
217{}
218
219NotShape_impl::~NotShape_impl(){}
220
221bool NotShape_impl::isInside(const Vector &point){
222 return !arg->isInside(point);
223}
224
225bool NotShape_impl::isOnSurface(const Vector &point){
226 return arg->isOnSurface(point);
227}
228
229Vector NotShape_impl::getNormal(const Vector &point) throw(NotOnSurfaceException){
230 return -1*arg->getNormal(point);
231}
232
233LineSegmentSet NotShape_impl::getLineIntersections(const Line &line){
234 return invert(arg->getLineIntersections(line));
235}
236
237string NotShape_impl::toString(){
238 return string("!") + arg->toString();
239}
240
241Shape operator!(const Shape &arg){
242 Shape::impl_ptr newImpl = Shape::impl_ptr(new NotShape_impl(getShapeImpl(arg)));
243 return Shape(newImpl);
244}
245
246/**************** global operations *********************************/
247ostream &operator<<(ostream &ost,const Shape &shape){
248 ost << shape.toString();
249 return ost;
250}
Note: See TracBrowser for help on using the repository browser.