source: src/Tesselation/unittests/Tesselation_BoundaryTriangleUnitTest.cpp@ 6dc3fe

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

Enhanced Tesselation_BoundaryTriangleUnitTest by check on ::GetClosestPointInsideTriangle().

  • checking on rotated triangle as well.
  • Property mode set to 100644
File size: 13.7 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
217/** UnitTest for Tesselation::GetClosestPointInsideTriangle()
218 *
219 * We check whether this function always returns a intersection inside the
220 * triangle.
221 *
222 */
223void TesselationBoundaryTriangleTest::GetClosestPointInsideTriangleTest()
224{
225 Vector TestIntersection;
226
227 {
228 // march through a cube mesh on triangle in xy plane
229 double n[3];
230 const double boundary = 4.;
231 const double step = 1.;
232 // go through the cube and check each point
233 for (n[0] = -boundary; n[0] <= boundary; n[0]+=step)
234 for (n[1] = -boundary; n[1] <= boundary; n[1]+=step)
235 for (n[2] = -boundary; n[2] <= boundary; n[2]+=step) {
236 const Vector testPoint(n[0], n[1], n[2]);
237 triangle->GetClosestPointInsideTriangle(testPoint, TestIntersection);
238 CPPUNIT_ASSERT( triangle->IsInsideTriangle( TestIntersection ));
239 }
240 }
241
242 delete triangle;
243 // create better triangle;
244 VECTORSET(std::vector) Vectors;
245 Vectors.push_back( Vector(0., 0., 0.) );
246 Vectors.push_back( Vector(0., 1., 0.) );
247 Vectors.push_back( Vector(1., 0., 0.) );
248 RealSpaceMatrix M;
249 M.setRotation(M_PI/3., M_PI/4., 2.*M_PI/3.);
250 Vectors.transform(M);
251 createTriangle(Vectors);
252
253 {
254 // march through a cube mesh on rotated triangle
255 double n[3];
256 const double boundary = 4.;
257 const double step = 1.;
258 // go through the cube and check each point
259 for (n[0] = -boundary; n[0] <= boundary; n[0]+=step)
260 for (n[1] = -boundary; n[1] <= boundary; n[1]+=step)
261 for (n[2] = -boundary; n[2] <= boundary; n[2]+=step) {
262 const Vector testPoint(n[0], n[1], n[2]);
263 triangle->GetClosestPointInsideTriangle(testPoint, TestIntersection);
264 CPPUNIT_ASSERT( triangle->IsInsideTriangle( TestIntersection ));
265 }
266 }
267}
268
269
270/** UnitTest for Tesselation::IsInnerPoint()
271 */
272void TesselationBoundaryTriangleTest::GetClosestPointOnPlaneTest()
273{
274 Vector TestIntersection;
275 Vector Point;
276
277 // simple test on y line
278 Point = Vector(-1.,0.5,0.);
279 CPPUNIT_ASSERT_EQUAL( 1., triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
280 Point = Vector(0.,0.5,0.);
281 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
282 Point = Vector(-4.,0.5,0.);
283 CPPUNIT_ASSERT_EQUAL( 16., triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
284 Point = Vector(0.,0.5,0.);
285 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
286
287 // simple test on x line
288 Point = Vector(0.5,-1.,0.);
289 CPPUNIT_ASSERT_EQUAL( 1., triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
290 Point = Vector(0.5,0.,0.);
291 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
292 Point = Vector(0.5,-6.,0.);
293 CPPUNIT_ASSERT_EQUAL( 36., triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
294 Point = Vector(0.5,0.,0.);
295 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
296
297 // simple test on slanted line
298 Point = Vector(1.,1.,0.);
299 CPPUNIT_ASSERT_EQUAL( 0.5, triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
300 Point = Vector(0.5,0.5,0.);
301 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
302 Point = Vector(5.,5.,0.);
303 CPPUNIT_ASSERT_EQUAL( 40.5, triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
304 Point = Vector(0.5,0.5,0.);
305 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
306
307 // simple test on first node
308 Point = Vector(-1.,-1.,0.);
309 CPPUNIT_ASSERT_EQUAL( 2., triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
310 Point = Vector(0.,0.,0.);
311 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
312
313 // simple test on second node
314 Point = Vector(0.,2.,0.);
315 CPPUNIT_ASSERT_EQUAL( 1., triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
316 Point = Vector(0.,1.,0.);
317 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
318
319 // simple test on third node
320 Point = Vector(2.,0.,0.);
321 CPPUNIT_ASSERT_EQUAL( 1., triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
322 Point = Vector(1.,0.,0.);
323 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
324};
325
326/** UnitTest for Tesselation::IsInnerPoint()
327 */
328void TesselationBoundaryTriangleTest::GetClosestPointOffPlaneTest()
329{
330 Vector TestIntersection;
331 Vector Point;
332
333 // straight down/up
334 Point = Vector(1./3.,1./3.,+5.);
335 CPPUNIT_ASSERT_EQUAL( 25. , triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
336 Point = Vector(1./3.,1./3.,0.);
337 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
338 Point = Vector(1./3.,1./3.,-5.);
339 CPPUNIT_ASSERT_EQUAL( 25. , triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
340 Point = Vector(1./3.,1./3.,0.);
341 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
342
343 // simple test on y line
344 Point = Vector(-1.,0.5,+2.);
345 CPPUNIT_ASSERT_EQUAL( 5., triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
346 Point = Vector(0.,0.5,0.);
347 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
348 Point = Vector(-1.,0.5,-3.);
349 CPPUNIT_ASSERT_EQUAL( 10., triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
350 Point = Vector(0.,0.5,0.);
351 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
352
353 // simple test on x line
354 Point = Vector(0.5,-1.,+1.);
355 CPPUNIT_ASSERT_EQUAL( 2., triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
356 Point = Vector(0.5,0.,0.);
357 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
358 Point = Vector(0.5,-1.,-2.);
359 CPPUNIT_ASSERT_EQUAL( 5., triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
360 Point = Vector(0.5,0.,0.);
361 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
362
363 // simple test on slanted line
364 Point = Vector(1.,1.,+3.);
365 CPPUNIT_ASSERT_EQUAL( 9.5, triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
366 Point = Vector(0.5,0.5,0.);
367 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
368 Point = Vector(1.,1.,-4.);
369 CPPUNIT_ASSERT_EQUAL( 16.5, triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
370 Point = Vector(0.5,0.5,0.);
371 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
372
373 // simple test on first node
374 Point = Vector(-1.,-1.,5.);
375 CPPUNIT_ASSERT_EQUAL( 27., triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
376 Point = Vector(0.,0.,0.);
377 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
378
379 // simple test on second node
380 Point = Vector(0.,2.,5.);
381 CPPUNIT_ASSERT_EQUAL( 26., triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
382 Point = Vector(0.,1.,0.);
383 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
384
385 // simple test on third node
386 Point = Vector(2.,0.,5.);
387 CPPUNIT_ASSERT_EQUAL( 26., triangle->GetClosestPointInsideTriangle(Point, TestIntersection) );
388 Point = Vector(1.,0.,0.);
389 CPPUNIT_ASSERT_EQUAL( true , Point == TestIntersection );
390};
Note: See TracBrowser for help on using the repository browser.