source: src/Tesselation/unittests/Tesselation_BoundaryTriangleUnitTest.cpp@ 471dec

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

Added BoundaryTriangleSet::IsInsideTriangle().

  • this is preparatory for finding a bug in GetClosestPointInsideTriangle().
  • refactored in-test triangle creation into distinct function.
  • added extensive unit test on this function.
  • Property mode set to 100644
File size: 11.2 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 * Tesselation_BoundaryTriangleUnitTest.cpp
10 *
11 * Created on: Jan 13, 2010
12 * Author: heber
13 */
14
15// include config.h
16#ifdef HAVE_CONFIG_H
17#include <config.h>
18#endif
19
20using namespace std;
21
22#include <cppunit/CompilerOutputter.h>
23#include <cppunit/extensions/TestFactoryRegistry.h>
24#include <cppunit/ui/text/TestRunner.h>
25
26#include <cstring>
27#include <iostream>
28
29#include "CodePatterns/Log.hpp"
30#include "Helpers/defs.hpp"
31#include "Atom/TesselPoint.hpp"
32#include "LinearAlgebra/Plane.hpp"
33#include "LinearAlgebra/VectorSet.hpp"
34#include "Tesselation/BoundaryPointSet.hpp"
35#include "Tesselation/BoundaryLineSet.hpp"
36#include "Tesselation/BoundaryTriangleSet.hpp"
37#include "Tesselation/CandidateForTesselation.hpp"
38
39#include "Tesselation_BoundaryTriangleUnitTest.hpp"
40
41#ifdef HAVE_TESTRUNNER
42#include "UnitTestMain.hpp"
43#endif /*HAVE_TESTRUNNER*/
44
45const double TesselationBoundaryTriangleTest::SPHERERADIUS=2.;
46
47/********************************************** Test classes **************************************/
48
49// Registers the fixture into the 'registry'
50CPPUNIT_TEST_SUITE_REGISTRATION( TesselationBoundaryTriangleTest );
51
52
53void TesselationBoundaryTriangleTest::createTriangle(const std::vector<Vector> &Vectors)
54{
55 CPPUNIT_ASSERT_EQUAL( (size_t)3, Vectors.size() );
56
57 // create nodes
58 for (size_t count = 0; count < NDIM; ++count) {
59 tesselpoints[count] = new TesselPoint;
60 tesselpoints[count]->setPosition( Vectors[count] );
61 tesselpoints[count]->setName(toString(count));
62 tesselpoints[count]->setNr(count);
63 points[count] = new BoundaryPointSet(tesselpoints[count]);
64 }
65
66 // create line
67 lines[0] = new BoundaryLineSet(points[0], points[1], 0);
68 lines[1] = new BoundaryLineSet(points[1], points[2], 1);
69 lines[2] = new BoundaryLineSet(points[0], points[2], 2);
70
71 // create triangle
72 triangle = new BoundaryTriangleSet(lines, 0);
73 Plane p(Vectors[0], Vectors[1], Vectors[2]);
74 triangle->GetNormalVector(p.getNormal());
75}
76
77void TesselationBoundaryTriangleTest::setUp()
78{
79 setVerbosity(5);
80
81 // create nodes
82 std::vector<Vector> Vectors;
83 Vectors.push_back( Vector(0., 0., 0.) );
84 Vectors.push_back( Vector(0., 1., 0.) );
85 Vectors.push_back( Vector(1., 0., 0.) );
86
87 // create triangle
88 createTriangle(Vectors);
89}
90
91void TesselationBoundaryTriangleTest::tearDown()
92{
93 delete(triangle);
94 for (int i=0;i<3;++i) {
95 // TesselPoint does not delete its vector as it only got a reference
96 delete tesselpoints[i];
97 }
98 logger::purgeInstance();
99 errorLogger::purgeInstance();
100};
101
102/** UnitTest for Tesselation::IsInsideTriangle()
103 */
104void TesselationBoundaryTriangleTest::IsInsideTriangleTest()
105{
106 // inside points
107 {
108 // check each endnode
109 for (size_t i=0; i< NDIM; ++i) {
110 const Vector testPoint(triangle->endpoints[i]->node->getPosition());
111 LOG(1, "INFO: Testing whether " << testPoint << " is an inner point.");
112 CPPUNIT_ASSERT( triangle->IsInsideTriangle( testPoint ) );
113 }
114 }
115
116 {
117 // check points along each BoundaryLine
118 for (size_t i=0; i< NDIM; ++i) {
119 Vector offset = triangle->endpoints[i%3]->node->getPosition();
120 Vector direction = triangle->endpoints[(i+1)%3]->node->getPosition() - offset;
121 for (double s = 0.1; s < 1.; s+= 0.1) {
122 Vector testPoint = offset + s*direction;
123 LOG(1, "INFO: Testing whether " << testPoint << " is an inner point.");
124 CPPUNIT_ASSERT( triangle->IsInsideTriangle( testPoint ) );
125 }
126 }
127 }
128
129 {
130 // check central point
131 Vector center;
132 triangle->GetCenter(center);
133 LOG(1, "INFO: Testing whether " << center << " is an inner point.");
134 CPPUNIT_ASSERT( triangle->IsInsideTriangle( center ) );
135 }
136
137 // outside points
138 {
139 // check points outside (i.e. those not in xy-plane through origin)
140 double n[3];
141 const double boundary = 4.;
142 const double step = 1.;
143 // go through the cube and check each point
144 for (n[0] = -boundary; n[0] <= boundary; n[0]+=step)
145 for (n[1] = -boundary; n[1] <= boundary; n[1]+=step)
146 for (n[2] = -boundary; n[2] <= boundary; n[2]+=step) {
147 const Vector testPoint(n[0], n[1], n[2]);
148 if (n[2] != 0) {
149 LOG(1, "INFO: Testing whether " << testPoint << " is not an inner point.");
150 CPPUNIT_ASSERT( !triangle->IsInsideTriangle( testPoint ) );
151 }
152 }
153 }
154
155 {
156 // check points within the plane but outside of triangle
157 double n[3];
158 const double boundary = 4.;
159 const double step = 1.;
160 n[2] = 0;
161 for (n[0] = -boundary; n[0] <= boundary; n[0]+=step)
162 for (n[1] = -boundary; n[1] <= boundary; n[1]+=step) {
163 const Vector testPoint(n[0], n[1], n[2]);
164 if ((n[0] >=0) && (n[1] >=0) && (n[0]<=1) && (n[1]<=1)) {
165 if (n[0]+n[1] <= 1) {
166 LOG(1, "INFO: Testing whether " << testPoint << " is an inner point.");
167 CPPUNIT_ASSERT( triangle->IsInsideTriangle( testPoint) );
168 } else {
169 LOG(1, "INFO: Testing whether " << testPoint << " is not an inner point.");
170 CPPUNIT_ASSERT( !triangle->IsInsideTriangle( testPoint) );
171 }
172 } else {
173 LOG(1, "INFO: Testing whether " << testPoint << " is not an inner point.");
174 CPPUNIT_ASSERT( !triangle->IsInsideTriangle( testPoint) );
175 }
176 }
177 }
178}
179
180/** UnitTest for Tesselation::IsInsideTriangle()
181 *
182 * We test for some specific points that occured in larger examples of the code.
183 *
184 */
185void TesselationBoundaryTriangleTest::IsInsideTriangle_specificTest()
186{
187 delete triangle;
188 {
189 // test is from --create-micelle 200 --radius 30. --position "0,0,0" of sles.data
190 // failure is: Intersection (23.1644,24.1867,65.1272) is not inside triangle [659|Na2451,O3652,Na3762].
191 const Vector testPoint(1.57318,1.57612,10.9874);
192 const Vector testIntersection(23.1644,24.1867,65.1272);
193 std::vector<Vector> vectors;
194 vectors.push_back( Vector(23.0563,30.4673,73.7555) );
195 vectors.push_back( Vector(25.473,25.1512,68.5467) );
196 vectors.push_back( Vector(23.1644,24.1867,65.1272) );
197 createTriangle(vectors);
198 CPPUNIT_ASSERT( triangle->IsInsideTriangle( testIntersection ) );
199 }
200}
201
202/** UnitTest for Tesselation::IsInnerPoint()
203 */
204void TesselationBoundaryTriangleTest::GetClosestPointOnPlaneTest()
205{
206 Vector TestIntersection;
207 Vector Point;
208
209 // simple test on y line
210 Point = Vector(-1.,0.5,0.);
211 CPPUNIT_ASSERT_EQUAL( 1., triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
212 Point = Vector(0.,0.5,0.);
213 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
214 Point = Vector(-4.,0.5,0.);
215 CPPUNIT_ASSERT_EQUAL( 16., triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
216 Point = Vector(0.,0.5,0.);
217 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
218
219 // simple test on x line
220 Point = Vector(0.5,-1.,0.);
221 CPPUNIT_ASSERT_EQUAL( 1., triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
222 Point = Vector(0.5,0.,0.);
223 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
224 Point = Vector(0.5,-6.,0.);
225 CPPUNIT_ASSERT_EQUAL( 36., triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
226 Point = Vector(0.5,0.,0.);
227 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
228
229 // simple test on slanted line
230 Point = Vector(1.,1.,0.);
231 CPPUNIT_ASSERT_EQUAL( 0.5, triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
232 Point = Vector(0.5,0.5,0.);
233 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
234 Point = Vector(5.,5.,0.);
235 CPPUNIT_ASSERT_EQUAL( 40.5, triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
236 Point = Vector(0.5,0.5,0.);
237 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
238
239 // simple test on first node
240 Point = Vector(-1.,-1.,0.);
241 CPPUNIT_ASSERT_EQUAL( 2., triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
242 Point = Vector(0.,0.,0.);
243 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
244
245 // simple test on second node
246 Point = Vector(0.,2.,0.);
247 CPPUNIT_ASSERT_EQUAL( 1., triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
248 Point = Vector(0.,1.,0.);
249 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
250
251 // simple test on third node
252 Point = Vector(2.,0.,0.);
253 CPPUNIT_ASSERT_EQUAL( 1., triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
254 Point = Vector(1.,0.,0.);
255 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
256};
257
258/** UnitTest for Tesselation::IsInnerPoint()
259 */
260void TesselationBoundaryTriangleTest::GetClosestPointOffPlaneTest()
261{
262 Vector TestIntersection;
263 Vector Point;
264
265 // straight down/up
266 Point = Vector(1./3.,1./3.,+5.);
267 CPPUNIT_ASSERT_EQUAL( 25. , triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
268 Point = Vector(1./3.,1./3.,0.);
269 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
270 Point = Vector(1./3.,1./3.,-5.);
271 CPPUNIT_ASSERT_EQUAL( 25. , triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
272 Point = Vector(1./3.,1./3.,0.);
273 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
274
275 // simple test on y line
276 Point = Vector(-1.,0.5,+2.);
277 CPPUNIT_ASSERT_EQUAL( 5., triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
278 Point = Vector(0.,0.5,0.);
279 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
280 Point = Vector(-1.,0.5,-3.);
281 CPPUNIT_ASSERT_EQUAL( 10., triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
282 Point = Vector(0.,0.5,0.);
283 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
284
285 // simple test on x line
286 Point = Vector(0.5,-1.,+1.);
287 CPPUNIT_ASSERT_EQUAL( 2., triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
288 Point = Vector(0.5,0.,0.);
289 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
290 Point = Vector(0.5,-1.,-2.);
291 CPPUNIT_ASSERT_EQUAL( 5., triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
292 Point = Vector(0.5,0.,0.);
293 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
294
295 // simple test on slanted line
296 Point = Vector(1.,1.,+3.);
297 CPPUNIT_ASSERT_EQUAL( 9.5, triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
298 Point = Vector(0.5,0.5,0.);
299 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
300 Point = Vector(1.,1.,-4.);
301 CPPUNIT_ASSERT_EQUAL( 16.5, triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
302 Point = Vector(0.5,0.5,0.);
303 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
304
305 // simple test on first node
306 Point = Vector(-1.,-1.,5.);
307 CPPUNIT_ASSERT_EQUAL( 27., triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
308 Point = Vector(0.,0.,0.);
309 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
310
311 // simple test on second node
312 Point = Vector(0.,2.,5.);
313 CPPUNIT_ASSERT_EQUAL( 26., triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
314 Point = Vector(0.,1.,0.);
315 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
316
317 // simple test on third node
318 Point = Vector(2.,0.,5.);
319 CPPUNIT_ASSERT_EQUAL( 26., triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
320 Point = Vector(1.,0.,0.);
321 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
322};
Note: See TracBrowser for help on using the repository browser.