source: src/Tesselation/unittests/Tesselation_BoundaryTriangleUnitTest.cpp@ c27ce7

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

BUG: Added another specific case to Tesselation_BoundaryTriangleUnitTest.

  • test case is again from larger filling example.
  • Note that this fails with current implementation of ::GetClosestPointInsideTriangle().
  • TESTFIX: Marked test as XFAIL.
  • Property mode set to 100644
File size: 15.5 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/RealSpaceMatrix.hpp"
34#include "LinearAlgebra/VectorSet.hpp"
35#include "Tesselation/BoundaryPointSet.hpp"
36#include "Tesselation/BoundaryLineSet.hpp"
37#include "Tesselation/BoundaryTriangleSet.hpp"
38#include "Tesselation/CandidateForTesselation.hpp"
39
40#include "Tesselation_BoundaryTriangleUnitTest.hpp"
41
42#ifdef HAVE_TESTRUNNER
43#include "UnitTestMain.hpp"
44#endif /*HAVE_TESTRUNNER*/
45
46const double TesselationBoundaryTriangleTest::SPHERERADIUS=2.;
47
48/********************************************** Test classes **************************************/
49
50// Registers the fixture into the 'registry'
51CPPUNIT_TEST_SUITE_REGISTRATION( TesselationBoundaryTriangleTest );
52
53
54void TesselationBoundaryTriangleTest::createTriangle(const std::vector<Vector> &Vectors)
55{
56 CPPUNIT_ASSERT_EQUAL( (size_t)3, Vectors.size() );
57
58 // create nodes
59 for (size_t count = 0; count < NDIM; ++count) {
60 tesselpoints[count] = new TesselPoint;
61 tesselpoints[count]->setPosition( Vectors[count] );
62 tesselpoints[count]->setName(toString(count));
63 tesselpoints[count]->setNr(count);
64 points[count] = new BoundaryPointSet(tesselpoints[count]);
65 }
66
67 // create line
68 lines[0] = new BoundaryLineSet(points[0], points[1], 0);
69 lines[1] = new BoundaryLineSet(points[1], points[2], 1);
70 lines[2] = new BoundaryLineSet(points[0], points[2], 2);
71
72 // create triangle
73 triangle = new BoundaryTriangleSet(lines, 0);
74 Plane p(Vectors[0], Vectors[1], Vectors[2]);
75 triangle->GetNormalVector(p.getNormal());
76}
77
78void TesselationBoundaryTriangleTest::setUp()
79{
80 setVerbosity(5);
81
82 // create nodes
83 std::vector<Vector> Vectors;
84 Vectors.push_back( Vector(0., 0., 0.) );
85 Vectors.push_back( Vector(0., 1., 0.) );
86 Vectors.push_back( Vector(1., 0., 0.) );
87
88 // create triangle
89 createTriangle(Vectors);
90}
91
92void TesselationBoundaryTriangleTest::tearDown()
93{
94 delete(triangle);
95 for (int i=0;i<3;++i) {
96 // TesselPoint does not delete its vector as it only got a reference
97 delete tesselpoints[i];
98 }
99 logger::purgeInstance();
100 errorLogger::purgeInstance();
101}
102
103/** UnitTest for Tesselation::IsInsideTriangle()
104 */
105void TesselationBoundaryTriangleTest::IsInsideTriangleTest()
106{
107 // inside points
108 {
109 // check each endnode
110 for (size_t i=0; i< NDIM; ++i) {
111 const Vector testPoint(triangle->endpoints[i]->node->getPosition());
112 LOG(1, "INFO: Testing whether " << testPoint << " is an inner point.");
113 CPPUNIT_ASSERT( triangle->IsInsideTriangle( testPoint ) );
114 }
115 }
116
117 {
118 // check points along each BoundaryLine
119 for (size_t i=0; i< NDIM; ++i) {
120 Vector offset = triangle->endpoints[i%3]->node->getPosition();
121 Vector direction = triangle->endpoints[(i+1)%3]->node->getPosition() - offset;
122 for (double s = 0.1; s < 1.; s+= 0.1) {
123 Vector testPoint = offset + s*direction;
124 LOG(1, "INFO: Testing whether " << testPoint << " is an inner point.");
125 CPPUNIT_ASSERT( triangle->IsInsideTriangle( testPoint ) );
126 }
127 }
128 }
129
130 {
131 // check central point
132 Vector center;
133 triangle->GetCenter(center);
134 LOG(1, "INFO: Testing whether " << center << " is an inner point.");
135 CPPUNIT_ASSERT( triangle->IsInsideTriangle( center ) );
136 }
137
138 // outside points
139 {
140 // check points outside (i.e. those not in xy-plane through origin)
141 double n[3];
142 const double boundary = 4.;
143 const double step = 1.;
144 // go through the cube and check each point
145 for (n[0] = -boundary; n[0] <= boundary; n[0]+=step)
146 for (n[1] = -boundary; n[1] <= boundary; n[1]+=step)
147 for (n[2] = -boundary; n[2] <= boundary; n[2]+=step) {
148 const Vector testPoint(n[0], n[1], n[2]);
149 if (n[2] != 0) {
150 LOG(1, "INFO: Testing whether " << testPoint << " is not an inner point.");
151 CPPUNIT_ASSERT( !triangle->IsInsideTriangle( testPoint ) );
152 }
153 }
154 }
155
156 {
157 // check points within the plane but outside of triangle
158 double n[3];
159 const double boundary = 4.;
160 const double step = 1.;
161 n[2] = 0;
162 for (n[0] = -boundary; n[0] <= boundary; n[0]+=step)
163 for (n[1] = -boundary; n[1] <= boundary; n[1]+=step) {
164 const Vector testPoint(n[0], n[1], n[2]);
165 if ((n[0] >=0) && (n[1] >=0) && (n[0]<=1) && (n[1]<=1)) {
166 if (n[0]+n[1] <= 1) {
167 LOG(1, "INFO: Testing whether " << testPoint << " is an inner point.");
168 CPPUNIT_ASSERT( triangle->IsInsideTriangle( testPoint) );
169 } else {
170 LOG(1, "INFO: Testing whether " << testPoint << " is not an inner point.");
171 CPPUNIT_ASSERT( !triangle->IsInsideTriangle( testPoint) );
172 }
173 } else {
174 LOG(1, "INFO: Testing whether " << testPoint << " is not an inner point.");
175 CPPUNIT_ASSERT( !triangle->IsInsideTriangle( testPoint) );
176 }
177 }
178 }
179}
180
181/** UnitTest for Tesselation::IsInsideTriangle()
182 *
183 * We test for some specific points that occured in larger examples of the code.
184 *
185 */
186void TesselationBoundaryTriangleTest::IsInsideTriangle_specificTest()
187{
188 {
189 delete triangle;
190 // test is from --create-micelle 200 --radius 30. --position "0,0,0" of sles.data
191 // failure is: Intersection (23.1644,24.1867,65.1272) is not inside triangle [659|Na2451,O3652,Na3762].
192 const Vector testPoint(1.57318,1.57612,10.9874);
193 const Vector testIntersection(23.1644,24.1867,65.1272);
194 std::vector<Vector> vectors;
195 vectors.push_back( Vector(23.0563,30.4673,73.7555) );
196 vectors.push_back( Vector(25.473,25.1512,68.5467) );
197 vectors.push_back( Vector(23.1644,24.1867,65.1272) );
198 createTriangle(vectors);
199 CPPUNIT_ASSERT( triangle->IsInsideTriangle( testIntersection ) );
200 }
201 {
202 delete triangle;
203 // test is from --create-micelle 200 --radius 30. --position "0,0,0" of sles.data
204 // failure is: Intersection (20.6787,70.655,71.5657) is not inside triangle [622|Na1197,Na2166,O3366].
205 // fix is lower LINALG_MYEPSILON (not std::numeric_limits<doubble>*100 but *1e-4)
206 const Vector testPoint(1.57318,14.185,61.2155);
207 const Vector testIntersection(20.67867516517798,70.65496977054023,71.56572984946152);
208 std::vector<Vector> vectors;
209 vectors.push_back( Vector(22.9592,68.7791,77.5907) );
210 vectors.push_back( Vector(18.4729,72.0386,68.08839999999999) );
211 vectors.push_back( Vector(20.3834,71.0154,70.1443) );
212 createTriangle(vectors);
213 CPPUNIT_ASSERT( triangle->IsInsideTriangle( testIntersection ) );
214 }
215 {
216 delete triangle;
217 // test is from --create-micelle 200 --radius 30. --position "0,0,0" of sles.data
218 // failure is:Intersection (27.56537519896,13.40256646925,6.672946688134) is not inside triangle [702|Na5016,O6388,Na6498].
219 // note that the Intersection cannot possibly lie be within the triangle!
220 const Vector testPoint();
221 const Vector testIntersection(27.56537519896,13.40256646925,6.672946688134);
222 std::vector<Vector> vectors;
223 vectors.push_back( Vector(10.7513,43.4247,48.4127) );
224 vectors.push_back( Vector(13.7119,37.0827,47.4203) );
225 vectors.push_back( Vector(14.6872,36.204,39.8043) );
226 createTriangle(vectors);
227 CPPUNIT_ASSERT( triangle->IsInsideTriangle( testIntersection ) );
228 }
229}
230
231/** UnitTest for Tesselation::GetClosestPointInsideTriangle()
232 *
233 * We check whether this function always returns a intersection inside the
234 * triangle.
235 *
236 */
237void TesselationBoundaryTriangleTest::GetClosestPointInsideTriangleTest()
238{
239 Vector TestIntersection;
240
241 {
242 // march through a cube mesh on triangle in xy plane
243 double n[3];
244 const double boundary = 4.;
245 const double step = 1.;
246 // go through the cube and check each point
247 for (n[0] = -boundary; n[0] <= boundary; n[0]+=step)
248 for (n[1] = -boundary; n[1] <= boundary; n[1]+=step)
249 for (n[2] = -boundary; n[2] <= boundary; n[2]+=step) {
250 const Vector testPoint(n[0], n[1], n[2]);
251 triangle->GetClosestPointInsideTriangle(testPoint, TestIntersection);
252 CPPUNIT_ASSERT( triangle->IsInsideTriangle( TestIntersection ));
253 }
254 }
255
256 delete triangle;
257 // create better triangle;
258 VECTORSET(std::vector) Vectors;
259 Vectors.push_back( Vector(0., 0., 0.) );
260 Vectors.push_back( Vector(0., 1., 0.) );
261 Vectors.push_back( Vector(1., 0., 0.) );
262 RealSpaceMatrix M;
263 M.setRotation(M_PI/3., M_PI/4., 2.*M_PI/3.);
264 Vectors.transform(M);
265 createTriangle(Vectors);
266
267 {
268 // march through a cube mesh on rotated triangle
269 double n[3];
270 const double boundary = 4.;
271 const double step = 1.;
272 // go through the cube and check each point
273 for (n[0] = -boundary; n[0] <= boundary; n[0]+=step)
274 for (n[1] = -boundary; n[1] <= boundary; n[1]+=step)
275 for (n[2] = -boundary; n[2] <= boundary; n[2]+=step) {
276 const Vector testPoint(n[0], n[1], n[2]);
277 triangle->GetClosestPointInsideTriangle(testPoint, TestIntersection);
278 CPPUNIT_ASSERT( triangle->IsInsideTriangle( TestIntersection ));
279 }
280 }
281}
282
283/** UnitTest for Tesselation::GetClosestPointInsideTriangle()
284 *
285 * We test for some specific points that occured in larger examples of the code.
286 *
287 */
288void TesselationBoundaryTriangleTest::GetClosestPointInsideTriangle_specificTest()
289{
290 {
291 delete triangle;
292 // test is from --create-micelle 200 --radius 30. --position "0,0,0" of sles.data
293 // failure is:Intersection (27.56537519896,13.40256646925,6.672946688134) is not inside triangle [702|Na5016,O6388,Na6498].
294 // note that the Intersection cannot possibly lie be within the triangle
295 // however, it is on its plane (off only by 2.7e-12)
296 const Vector testPoint(27.56537519896,13.40256646925,6.672946688134);
297 Vector testIntersection;
298 std::vector<Vector> vectors;
299 vectors.push_back( Vector(10.7513,43.4247,48.4127) );
300 vectors.push_back( Vector(13.7119,37.0827,47.4203) );
301 vectors.push_back( Vector(14.6872,36.204,39.8043) );
302 createTriangle(vectors);
303 triangle->GetClosestPointInsideTriangle(testPoint, testIntersection);
304 CPPUNIT_ASSERT_EQUAL ( testPoint, testIntersection );
305 }
306}
307
308/** UnitTest for Tesselation::IsInnerPoint()
309 */
310void TesselationBoundaryTriangleTest::GetClosestPointOnPlaneTest()
311{
312 Vector TestIntersection;
313 Vector Point;
314
315 // simple test on y line
316 Point = Vector(-1.,0.5,0.);
317 CPPUNIT_ASSERT_EQUAL( 1., triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
318 Point = Vector(0.,0.5,0.);
319 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
320 Point = Vector(-4.,0.5,0.);
321 CPPUNIT_ASSERT_EQUAL( 16., triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
322 Point = Vector(0.,0.5,0.);
323 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
324
325 // simple test on x line
326 Point = Vector(0.5,-1.,0.);
327 CPPUNIT_ASSERT_EQUAL( 1., triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
328 Point = Vector(0.5,0.,0.);
329 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
330 Point = Vector(0.5,-6.,0.);
331 CPPUNIT_ASSERT_EQUAL( 36., triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
332 Point = Vector(0.5,0.,0.);
333 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
334
335 // simple test on slanted line
336 Point = Vector(1.,1.,0.);
337 CPPUNIT_ASSERT_EQUAL( 0.5, triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
338 Point = Vector(0.5,0.5,0.);
339 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
340 Point = Vector(5.,5.,0.);
341 CPPUNIT_ASSERT_EQUAL( 40.5, triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
342 Point = Vector(0.5,0.5,0.);
343 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
344
345 // simple test on first node
346 Point = Vector(-1.,-1.,0.);
347 CPPUNIT_ASSERT_EQUAL( 2., triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
348 Point = Vector(0.,0.,0.);
349 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
350
351 // simple test on second node
352 Point = Vector(0.,2.,0.);
353 CPPUNIT_ASSERT_EQUAL( 1., triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
354 Point = Vector(0.,1.,0.);
355 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
356
357 // simple test on third node
358 Point = Vector(2.,0.,0.);
359 CPPUNIT_ASSERT_EQUAL( 1., triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
360 Point = Vector(1.,0.,0.);
361 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
362};
363
364/** UnitTest for Tesselation::IsInnerPoint()
365 */
366void TesselationBoundaryTriangleTest::GetClosestPointOffPlaneTest()
367{
368 Vector TestIntersection;
369 Vector Point;
370
371 // straight down/up
372 Point = Vector(1./3.,1./3.,+5.);
373 CPPUNIT_ASSERT_EQUAL( 25. , triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
374 Point = Vector(1./3.,1./3.,0.);
375 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
376 Point = Vector(1./3.,1./3.,-5.);
377 CPPUNIT_ASSERT_EQUAL( 25. , triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
378 Point = Vector(1./3.,1./3.,0.);
379 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
380
381 // simple test on y line
382 Point = Vector(-1.,0.5,+2.);
383 CPPUNIT_ASSERT_EQUAL( 5., triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
384 Point = Vector(0.,0.5,0.);
385 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
386 Point = Vector(-1.,0.5,-3.);
387 CPPUNIT_ASSERT_EQUAL( 10., triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
388 Point = Vector(0.,0.5,0.);
389 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
390
391 // simple test on x line
392 Point = Vector(0.5,-1.,+1.);
393 CPPUNIT_ASSERT_EQUAL( 2., triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
394 Point = Vector(0.5,0.,0.);
395 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
396 Point = Vector(0.5,-1.,-2.);
397 CPPUNIT_ASSERT_EQUAL( 5., triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
398 Point = Vector(0.5,0.,0.);
399 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
400
401 // simple test on slanted line
402 Point = Vector(1.,1.,+3.);
403 CPPUNIT_ASSERT_EQUAL( 9.5, triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
404 Point = Vector(0.5,0.5,0.);
405 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
406 Point = Vector(1.,1.,-4.);
407 CPPUNIT_ASSERT_EQUAL( 16.5, triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
408 Point = Vector(0.5,0.5,0.);
409 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
410
411 // simple test on first node
412 Point = Vector(-1.,-1.,5.);
413 CPPUNIT_ASSERT_EQUAL( 27., triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
414 Point = Vector(0.,0.,0.);
415 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
416
417 // simple test on second node
418 Point = Vector(0.,2.,5.);
419 CPPUNIT_ASSERT_EQUAL( 26., triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
420 Point = Vector(0.,1.,0.);
421 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
422
423 // simple test on third node
424 Point = Vector(2.,0.,5.);
425 CPPUNIT_ASSERT_EQUAL( 26., triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
426 Point = Vector(1.,0.,0.);
427 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
428};
Note: See TracBrowser for help on using the repository browser.