source: src/Shapes/Shape.cpp@ a88452

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 a88452 was 5a8d61, checked in by Frederik Heber <heber@…>, 13 years ago

Added new function to all Shape: getHomogeneousPointsInVolume().

  • basically it is not implemented except for ShapeOps, yet.
  • there is an initial unit test Shape_HomogeneousPointsUnitTest.
  • Property mode set to 100644
File size: 11.9 KB
Line 
1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2010-2012 University of Bonn. All rights reserved.
5 * Please see the LICENSE file or "Copyright notice" in builder.cpp for details.
6 */
7
8/*
9 * Shape.cpp
10 *
11 * Created on: Jun 18, 2010
12 * Author: crueger
13 */
14
15// include config.h
16#ifdef HAVE_CONFIG_H
17#include <config.h>
18#endif
19
20#include "CodePatterns/MemDebug.hpp"
21
22#include "CodePatterns/Assert.hpp"
23#include "LinearAlgebra/Vector.hpp"
24
25#include "Shapes/Shape.hpp"
26#include "Shapes/Shape_impl.hpp"
27#include "Shapes/ShapeExceptions.hpp"
28#include "Shapes/ShapeType.hpp"
29
30#include <algorithm>
31#include <limits>
32#include <string>
33
34
35Shape::Shape(const Shape& src) :
36 impl(src.getImpl())
37{}
38
39Shape::~Shape(){}
40
41bool Shape::isInside(const Vector &point) const{
42 return impl->isInside(point);
43}
44
45bool Shape::isOnSurface(const Vector &point) const{
46 return impl->isOnSurface(point);
47}
48
49Vector Shape::getNormal(const Vector &point) const throw (NotOnSurfaceException){
50 return impl->getNormal(point);
51}
52
53Vector Shape::getCenter() const{
54 return impl->getCenter();
55}
56
57double Shape::getRadius() const{
58 return impl->getRadius();
59}
60
61LineSegmentSet Shape::getLineIntersections(const Line &line) const{
62 return impl->getLineIntersections(line);
63}
64
65std::vector<Vector> Shape::getHomogeneousPointsOnSurface(const size_t N) const {
66 return impl->getHomogeneousPointsOnSurface(N);
67}
68
69std::vector<Vector> Shape::getHomogeneousPointsInVolume(const size_t N) const {
70 return impl->getHomogeneousPointsInVolume(N);
71}
72
73Shape::Shape(Shape::impl_ptr _impl) :
74 impl(_impl)
75{}
76
77Shape &Shape::operator=(const Shape& rhs){
78 if(&rhs!=this){
79 impl=rhs.getImpl();
80 }
81 return *this;
82}
83
84bool Shape::operator==(const Shape &rhs) const{
85 return (this->getType() == rhs.getType());
86}
87
88std::string Shape::toString() const{
89 return impl->toString();
90}
91
92enum ShapeType Shape::getType() const{
93 return impl->getType();
94}
95
96Shape::impl_ptr Shape::getImpl() const{
97 return impl;
98}
99
100// allows arbitrary friendship, but only if implementation is known
101Shape::impl_ptr getShapeImpl(const Shape &shape){
102 return shape.getImpl();
103}
104
105/***************************** Some simple Shapes ***************************/
106
107Shape Everywhere(){
108 static Shape::impl_ptr impl = Shape::impl_ptr(new Everywhere_impl());
109 return Shape(impl);
110}
111
112Shape Nowhere(){
113 static Shape::impl_ptr impl = Shape::impl_ptr(new Nowhere_impl());
114 return Shape(impl);
115}
116
117/****************************** Operators ***********************************/
118
119// AND
120
121AndShape_impl::AndShape_impl(const Shape::impl_ptr &_lhs, const Shape::impl_ptr &_rhs) :
122 lhs(_lhs),rhs(_rhs)
123{}
124
125AndShape_impl::~AndShape_impl(){}
126
127bool AndShape_impl::isInside(const Vector &point) const{
128 return lhs->isInside(point) && rhs->isInside(point);
129}
130
131bool AndShape_impl::isOnSurface(const Vector &point) const{
132 // check the number of surfaces that this point is on
133 int surfaces =0;
134 surfaces += lhs->isOnSurface(point);
135 surfaces += rhs->isOnSurface(point);
136
137 switch(surfaces){
138 case 0:
139 return false;
140 // no break necessary
141 case 1:
142 // if it is inside for the object where it does not lie on
143 // the surface the whole point lies inside
144 return (lhs->isOnSurface(point) && rhs->isInside(point)) ||
145 (rhs->isOnSurface(point) && lhs->isInside(point));
146 // no break necessary
147 case 2:
148 {
149 // it lies on both Shapes... could be an edge or an inner point
150 // test the direction of the normals
151 Vector direction=lhs->getNormal(point)+rhs->getNormal(point);
152 // if the directions are opposite we lie on the inside
153 return !direction.IsZero();
154 }
155 // no break necessary
156 default:
157 // if this happens there is something wrong
158 ASSERT(0,"Default case should have never been used");
159 }
160 return false; // never reached
161}
162
163Vector AndShape_impl::getNormal(const Vector &point) const throw (NotOnSurfaceException){
164 Vector res;
165 if(!isOnSurface(point)){
166 throw NotOnSurfaceException() << ShapeVector(&point);
167 }
168 res += lhs->isOnSurface(point)?lhs->getNormal(point):zeroVec;
169 res += rhs->isOnSurface(point)?rhs->getNormal(point):zeroVec;
170 res.Normalize();
171 return res;
172}
173
174Vector AndShape_impl::getCenter() const
175{
176 // calculate closest position on sphere surface to other center ..
177 const Vector rhsDistance = rhs->getCenter() + rhs->getRadius()*((lhs->getCenter() - rhs->getCenter()).getNormalized());
178 const Vector lhsDistance = lhs->getCenter() + lhs->getRadius()*((rhs->getCenter() - lhs->getCenter()).getNormalized());
179 // .. and then it's right in between those two
180 return 0.5*(rhsDistance + lhsDistance);
181}
182
183double AndShape_impl::getRadius() const
184{
185 const double distance = (lhs->getCenter() - rhs->getCenter()).Norm();
186 const double minradii = std::min(lhs->getRadius(), rhs->getRadius());
187 // if no intersection
188 if (distance > (lhs->getRadius() + rhs->getRadius()))
189 return 0.;
190 else // if intersection it can only be the smaller one
191 return minradii;
192}
193
194LineSegmentSet AndShape_impl::getLineIntersections(const Line &line) const{
195 return intersect(lhs->getLineIntersections(line),rhs->getLineIntersections(line));
196}
197
198std::string AndShape_impl::toString() const{
199 return std::string("(") + lhs->toString() + std::string("&&") + rhs->toString() + std::string(")");
200}
201
202enum ShapeType AndShape_impl::getType() const{
203 return CombinedType;
204}
205
206std::vector<Vector> AndShape_impl::getHomogeneousPointsOnSurface(const size_t N) const {
207 std::vector<Vector> PointsOnSurface_lhs = lhs->getHomogeneousPointsOnSurface(N);
208 std::vector<Vector> PointsOnSurface_rhs = rhs->getHomogeneousPointsOnSurface(N);
209 std::vector<Vector> PointsOnSurface;
210
211 for (std::vector<Vector>::const_iterator iter = PointsOnSurface_lhs.begin(); iter != PointsOnSurface_lhs.end(); ++iter) {
212 if (rhs->isInside(*iter))
213 PointsOnSurface.push_back(*iter);
214 }
215 for (std::vector<Vector>::const_iterator iter = PointsOnSurface_rhs.begin(); iter != PointsOnSurface_rhs.end(); ++iter) {
216 if (lhs->isInside(*iter))
217 PointsOnSurface.push_back(*iter);
218 }
219
220 return PointsOnSurface;
221}
222
223std::vector<Vector> AndShape_impl::getHomogeneousPointsInVolume(const size_t N) const {
224 ASSERT(0,
225 "AndShape_impl::getHomogeneousPointsInVolume() - not implemented.");
226 return std::vector<Vector>();
227}
228
229
230Shape operator&&(const Shape &lhs,const Shape &rhs){
231 Shape::impl_ptr newImpl = Shape::impl_ptr(new AndShape_impl(getShapeImpl(lhs),getShapeImpl(rhs)));
232 return Shape(newImpl);
233}
234
235// OR
236
237OrShape_impl::OrShape_impl(const Shape::impl_ptr &_lhs, const Shape::impl_ptr &_rhs) :
238 lhs(_lhs),rhs(_rhs)
239{}
240
241OrShape_impl::~OrShape_impl(){}
242
243bool OrShape_impl::isInside(const Vector &point) const{
244 return rhs->isInside(point) || lhs->isInside(point);
245}
246
247bool OrShape_impl::isOnSurface(const Vector &point) const{
248 // check the number of surfaces that this point is on
249 int surfaces =0;
250 surfaces += lhs->isOnSurface(point);
251 surfaces += rhs->isOnSurface(point);
252
253 switch(surfaces){
254 case 0:
255 return false;
256 // no break necessary
257 case 1:
258 // if it is inside for the object where it does not lie on
259 // the surface the whole point lies inside
260 return (lhs->isOnSurface(point) && !rhs->isInside(point)) ||
261 (rhs->isOnSurface(point) && !lhs->isInside(point));
262 // no break necessary
263 case 2:
264 {
265 // it lies on both Shapes... could be an edge or an inner point
266 // test the direction of the normals
267 Vector direction=lhs->getNormal(point)+rhs->getNormal(point);
268 // if the directions are opposite we lie on the inside
269 return !direction.IsZero();
270 }
271 // no break necessary
272 default:
273 // if this happens there is something wrong
274 ASSERT(0,"Default case should have never been used");
275 }
276 return false; // never reached
277}
278
279Vector OrShape_impl::getNormal(const Vector &point) const throw (NotOnSurfaceException){
280 Vector res;
281 if(!isOnSurface(point)){
282 throw NotOnSurfaceException() << ShapeVector(&point);
283 }
284 res += lhs->isOnSurface(point)?lhs->getNormal(point):zeroVec;
285 res += rhs->isOnSurface(point)?rhs->getNormal(point):zeroVec;
286 res.Normalize();
287 return res;
288}
289
290Vector OrShape_impl::getCenter() const
291{
292 // calculate furthest position on sphere surface to other center ..
293 const Vector rhsDistance = rhs->getCenter() + rhs->getRadius()*((rhs->getCenter() - lhs->getCenter()).getNormalized());
294 const Vector lhsDistance = lhs->getCenter() + lhs->getRadius()*((lhs->getCenter() - rhs->getCenter()).getNormalized());
295 // .. and then it's right in between those two
296 return .5*(rhsDistance + lhsDistance);
297}
298
299double OrShape_impl::getRadius() const
300{
301 const Vector rhsDistance = rhs->getCenter() + rhs->getRadius()*((rhs->getCenter() - lhs->getCenter()).getNormalized());
302 const Vector lhsDistance = lhs->getCenter() + lhs->getRadius()*((lhs->getCenter() - rhs->getCenter()).getNormalized());
303 return .5*(rhsDistance - lhsDistance).Norm();
304}
305
306LineSegmentSet OrShape_impl::getLineIntersections(const Line &line) const{
307 return merge(lhs->getLineIntersections(line),rhs->getLineIntersections(line));
308}
309
310std::string OrShape_impl::toString() const{
311 return std::string("(") + lhs->toString() + std::string("||") + rhs->toString() + std::string(")");
312}
313
314enum ShapeType OrShape_impl::getType() const{
315 return CombinedType;
316}
317
318std::vector<Vector> OrShape_impl::getHomogeneousPointsOnSurface(const size_t N) const {
319 std::vector<Vector> PointsOnSurface_lhs = lhs->getHomogeneousPointsOnSurface(N);
320 std::vector<Vector> PointsOnSurface_rhs = rhs->getHomogeneousPointsOnSurface(N);
321 std::vector<Vector> PointsOnSurface;
322
323 for (std::vector<Vector>::const_iterator iter = PointsOnSurface_lhs.begin(); iter != PointsOnSurface_lhs.end(); ++iter) {
324 if (!rhs->isInside(*iter))
325 PointsOnSurface.push_back(*iter);
326 }
327 for (std::vector<Vector>::const_iterator iter = PointsOnSurface_rhs.begin(); iter != PointsOnSurface_rhs.end(); ++iter) {
328 if (!lhs->isInside(*iter))
329 PointsOnSurface.push_back(*iter);
330 }
331
332 return PointsOnSurface;
333}
334
335std::vector<Vector> OrShape_impl::getHomogeneousPointsInVolume(const size_t N) const {
336 ASSERT(0,
337 "OrShape_impl::getHomogeneousPointsInVolume() - not implemented.");
338 return std::vector<Vector>();
339}
340
341Shape operator||(const Shape &lhs,const Shape &rhs){
342 Shape::impl_ptr newImpl = Shape::impl_ptr(new OrShape_impl(getShapeImpl(lhs),getShapeImpl(rhs)));
343 return Shape(newImpl);
344}
345
346// NOT
347
348NotShape_impl::NotShape_impl(const Shape::impl_ptr &_arg) :
349 arg(_arg)
350{}
351
352NotShape_impl::~NotShape_impl(){}
353
354bool NotShape_impl::isInside(const Vector &point) const{
355 return !arg->isInside(point);
356}
357
358bool NotShape_impl::isOnSurface(const Vector &point) const{
359 return arg->isOnSurface(point);
360}
361
362Vector NotShape_impl::getNormal(const Vector &point) const throw(NotOnSurfaceException){
363 return -1.*arg->getNormal(point);
364}
365
366Vector NotShape_impl::getCenter() const
367{
368 return arg->getCenter();
369}
370
371double NotShape_impl::getRadius() const
372{
373 return std::numeric_limits<double>::infinity();
374}
375
376LineSegmentSet NotShape_impl::getLineIntersections(const Line &line) const{
377 return invert(arg->getLineIntersections(line));
378}
379
380std::string NotShape_impl::toString() const{
381 return std::string("!") + arg->toString();
382}
383
384enum ShapeType NotShape_impl::getType() const{
385 return CombinedType;
386}
387
388std::vector<Vector> NotShape_impl::getHomogeneousPointsOnSurface(const size_t N) const {
389 // surfaces are the same, only normal direction is different
390 return arg->getHomogeneousPointsOnSurface(N);
391}
392
393std::vector<Vector> NotShape_impl::getHomogeneousPointsInVolume(const size_t N) const {
394 ASSERT(0,
395 "NotShape_impl::getHomogeneousPointsInVolume() - not implemented.");
396 return std::vector<Vector>();
397}
398
399Shape operator!(const Shape &arg){
400 Shape::impl_ptr newImpl = Shape::impl_ptr(new NotShape_impl(getShapeImpl(arg)));
401 return Shape(newImpl);
402}
403
404/**************** global operations *********************************/
405std::ostream &operator<<(std::ostream &ost,const Shape &shape){
406 ost << shape.toString();
407 return ost;
408}
Note: See TracBrowser for help on using the repository browser.