RINGMesh  Version 5.0.0
A programming library for geological model meshes
test-transrot.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012-2017, Association Scientifique pour la Geologie et ses
3  * Applications (ASGA). All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  * * Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * * Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * * Neither the name of ASGA nor the
13  * names of its contributors may be used to endorse or promote products
14  * derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
18  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ASGA BE LIABLE FOR ANY DIRECT,
20  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  *
27  * http://www.ring-team.org
28  *
29  * RING Project
30  * Ecole Nationale Superieure de Geologie - GeoRessources
31  * 2 Rue du Doyen Marcel Roubault - TSA 70605
32  * 54518 VANDOEUVRE-LES-NANCY
33  * FRANCE
34  */
35 
36 #include <ringmesh/ringmesh_tests_config.h>
37 
39 
42 
47 using namespace RINGMesh;
48 
49 void build_geomodel( GeoModel3D& geomodel )
50 {
51  GeoModelBuilder3D builder( geomodel );
52 
53  vec3 v0( 0, 0, 0 );
54  vec3 v1( 1, 0, 0 );
55  vec3 v2( 1, 1, 0 );
56  vec3 v3( 0, 1, 0 );
57  vec3 v4( 0, 0, 1 );
58  vec3 v5( 1, 0, 1 );
59  vec3 v6( 1, 1, 1 );
60  vec3 v7( 0, 1, 1 );
61 
62  std::vector< index_t > triangles;
63  triangles.push_back( 0 );
64  triangles.push_back( 1 );
65  triangles.push_back( 2 );
66  triangles.push_back( 0 );
67  triangles.push_back( 2 );
68  triangles.push_back( 3 );
69 
70  std::vector< index_t > surface_facet_ptr;
71  surface_facet_ptr.push_back( 0 );
72  surface_facet_ptr.push_back( 3 );
73  surface_facet_ptr.push_back( 6 );
74 
75  std::vector< vec3 > vertices( 4 );
76  gmme_id id;
77 
78  id = builder.topology.create_mesh_entity( Surface3D::type_name_static() );
79  vertices[0] = v0;
80  vertices[1] = v1;
81  vertices[2] = v2;
82  vertices[3] = v3;
83  builder.geometry.set_surface_geometry(
84  id.index(), vertices, triangles, surface_facet_ptr );
85 
86  id = builder.topology.create_mesh_entity( Surface3D::type_name_static() );
87  vertices[0] = v1;
88  vertices[1] = v5;
89  vertices[2] = v6;
90  vertices[3] = v2;
91  builder.geometry.set_surface_geometry(
92  id.index(), vertices, triangles, surface_facet_ptr );
93 
94  id = builder.topology.create_mesh_entity( Surface3D::type_name_static() );
95  vertices[0] = v4;
96  vertices[1] = v5;
97  vertices[2] = v6;
98  vertices[3] = v7;
99  builder.geometry.set_surface_geometry(
100  id.index(), vertices, triangles, surface_facet_ptr );
101 
102  id = builder.topology.create_mesh_entity( Surface3D::type_name_static() );
103  vertices[0] = v0;
104  vertices[1] = v3;
105  vertices[2] = v7;
106  vertices[3] = v4;
107  builder.geometry.set_surface_geometry(
108  id.index(), vertices, triangles, surface_facet_ptr );
109 
110  id = builder.topology.create_mesh_entity( Surface3D::type_name_static() );
111  vertices[0] = v3;
112  vertices[1] = v2;
113  vertices[2] = v6;
114  vertices[3] = v7;
115  builder.geometry.set_surface_geometry(
116  id.index(), vertices, triangles, surface_facet_ptr );
117 
118  id = builder.topology.create_mesh_entity( Surface3D::type_name_static() );
119  vertices[0] = v0;
120  vertices[1] = v1;
121  vertices[2] = v5;
122  vertices[3] = v4;
123  builder.geometry.set_surface_geometry(
124  id.index(), vertices, triangles, surface_facet_ptr );
125 }
126 
127 void check_vertex( const vec3& in, const vec3& result )
128 {
129  if( in != result )
130  {
131  throw RINGMeshException( "Test", "Verification failed" );
132  }
133 }
134 
135 void test_translate( GeoModel3D& geomodel )
136 {
137  Logger::out( "TEST", "Test translation" );
138  vec3 translation_vector( 1., 2.5, -3.5 );
139  translate( geomodel, translation_vector );
140 
141  const GeoModelMeshVertices3D& vertices = geomodel.mesh.vertices;
142  check_vertex( vertices.vertex( 0 ), vec3( 1., 2.5, -3.5 ) );
143  check_vertex( vertices.vertex( 1 ), vec3( 2., 2.5, -3.5 ) );
144  check_vertex( vertices.vertex( 2 ), vec3( 2., 3.5, -3.5 ) );
145  check_vertex( vertices.vertex( 3 ), vec3( 1., 3.5, -3.5 ) );
146  check_vertex( vertices.vertex( 4 ), vec3( 2., 2.5, -2.5 ) );
147  check_vertex( vertices.vertex( 5 ), vec3( 2., 3.5, -2.5 ) );
148  check_vertex( vertices.vertex( 6 ), vec3( 1., 2.5, -2.5 ) );
149  check_vertex( vertices.vertex( 7 ), vec3( 1., 3.5, -2.5 ) );
150 }
151 
152 void test_rotation( GeoModel3D& geomodel )
153 {
154  Logger::out( "TEST", "Test rotation" );
155  vec3 origin( 1., 2.5, -3.5 );
156  vec3 axis( 0, 0, 1 );
157  rotate( geomodel, origin, axis, 90, true );
158 
159  const GeoModelMeshVertices3D& vertices = geomodel.mesh.vertices;
160  check_vertex( vertices.vertex( 0 ), vec3( 1., 2.5, -3.5 ) );
161  check_vertex( vertices.vertex( 1 ), vec3( 1., 3.5, -3.5 ) );
162  check_vertex( vertices.vertex( 2 ), vec3( 0., 3.5, -3.5 ) );
163  check_vertex( vertices.vertex( 3 ), vec3( 0., 2.5, -3.5 ) );
164  check_vertex( vertices.vertex( 4 ), vec3( 1., 3.5, -2.5 ) );
165  check_vertex( vertices.vertex( 5 ), vec3( 0., 3.5, -2.5 ) );
166  check_vertex( vertices.vertex( 6 ), vec3( 1., 2.5, -2.5 ) );
167  check_vertex( vertices.vertex( 7 ), vec3( 0., 2.5, -2.5 ) );
168 }
169 
171  const GEO::Matrix< 4, double >& lhs, const GEO::Matrix< 4, double >& rhs )
172 {
173  for( index_t mat_i : range( 4 ) )
174  {
175  for( index_t mat_j : range( 4 ) )
176  {
177  double diff = lhs( mat_i, mat_j ) - rhs( mat_i, mat_j );
178  if( std::fabs( diff ) > global_epsilon )
179  {
180  throw RINGMeshException( "Test", "Error in rotation matrix" );
181  }
182  }
183  }
184 }
185 
187 {
188  const vec3 origin( 0, 0, 0 );
189  const double pi = M_PI;
190  const double step = 0.1;
191 
192  GEO::Matrix< 4, double > rot_mat_degree;
193  GEO::Matrix< 4, double > rot_mat_radian;
194  GEO::Matrix< 4, double > result;
195  result( 0, 3 ) = 0;
196  result( 1, 3 ) = 0;
197  result( 2, 3 ) = 0;
198  result( 3, 0 ) = 0;
199  result( 3, 1 ) = 0;
200  result( 3, 2 ) = 0;
201  result( 3, 3 ) = 1;
202 
203  // Tests rotation along x axis
204  vec3 axis( 1, 0, 0 );
205  for( double angle = 0.; angle <= 360.; angle += step )
206  {
207  rot_mat_degree =
208  rotation_matrix_about_arbitrary_axis( origin, axis, angle, true );
209  double angle_rad = angle * pi / 180.;
210  rot_mat_radian = rotation_matrix_about_arbitrary_axis(
211  origin, axis, angle_rad, false );
212  result( 0, 0 ) = 1;
213  result( 0, 1 ) = 0;
214  result( 0, 2 ) = 0;
215 
216  result( 1, 0 ) = 0;
217  result( 1, 1 ) = std::cos( angle_rad );
218  result( 1, 2 ) = -std::sin( angle_rad );
219 
220  result( 2, 0 ) = 0;
221  result( 2, 1 ) = std::sin( angle_rad );
222  result( 2, 2 ) = std::cos( angle_rad );
223 
224  check_matrices( rot_mat_degree, result );
225  check_matrices( rot_mat_radian, result );
226  }
227 
228  // Tests rotation along y axis
229  axis = vec3( 0, 1, 0 );
230  for( double angle = 0.; angle <= 360.; angle += step )
231  {
232  rot_mat_degree =
233  rotation_matrix_about_arbitrary_axis( origin, axis, angle, true );
234  double angle_rad = angle * pi / 180.;
235  rot_mat_radian = rotation_matrix_about_arbitrary_axis(
236  origin, axis, angle_rad, false );
237  result( 0, 0 ) = std::cos( angle_rad );
238  result( 0, 1 ) = 0;
239  result( 0, 2 ) = std::sin( angle_rad );
240 
241  result( 1, 0 ) = 0;
242  result( 1, 1 ) = 1;
243  result( 1, 2 ) = 0;
244 
245  result( 2, 0 ) = -std::sin( angle_rad );
246  result( 2, 1 ) = 0;
247  result( 2, 2 ) = std::cos( angle_rad );
248 
249  check_matrices( rot_mat_degree, result );
250  check_matrices( rot_mat_radian, result );
251  }
252 
253  // Tests rotation along z axis
254  axis = vec3( 0, 0, 1 );
255  for( double angle = 0.; angle <= 360.; angle += step )
256  {
257  rot_mat_degree =
258  rotation_matrix_about_arbitrary_axis( origin, axis, angle, true );
259  double angle_rad = angle * pi / 180.;
260  rot_mat_radian = rotation_matrix_about_arbitrary_axis(
261  origin, axis, angle_rad, false );
262  result( 0, 0 ) = std::cos( angle_rad );
263  result( 0, 1 ) = -std::sin( angle_rad );
264  result( 0, 2 ) = 0;
265 
266  result( 1, 0 ) = std::sin( angle_rad );
267  result( 1, 1 ) = std::cos( angle_rad );
268  result( 1, 2 ) = 0;
269 
270  result( 2, 0 ) = 0;
271  result( 2, 1 ) = 0;
272  result( 2, 2 ) = 1;
273 
274  check_matrices( rot_mat_degree, result );
275  check_matrices( rot_mat_radian, result );
276  }
277 }
278 
279 int main()
280 {
281  using namespace RINGMesh;
282 
283  try
284  {
286 
287  GeoModel3D geomodel;
288  build_geomodel( geomodel );
289  test_translate( geomodel );
291  test_rotation( geomodel );
292  }
293  catch( const RINGMeshException& e )
294  {
295  Logger::err( e.category(), e.what() );
296  return 1;
297  }
298  catch( const std::exception& e )
299  {
300  Logger::err( "Exception", e.what() );
301  return 1;
302  }
303  Logger::out( "TEST", "SUCCESS" );
304  return 0;
305 }
int main()
vecn< 3 > vec3
Definition: types.h:76
void build_geomodel(GeoModel3D &geomodel)
void RINGMESH_API rotate(GeoModel3D &geomodel, const vec3 &origin, const vec3 &axis, double angle, bool degrees=false)
Rotate the boundary geomodel.
void translate(GeoModel< DIMENSION > &geomodel, const vecn< DIMENSION > &translation_vector)
Translates the boundary geomodel by a vector.
void test_rotation(GeoModel3D &geomodel)
GEO::Matrix< 4, double > RINGMESH_API rotation_matrix_about_arbitrary_axis(const vec3 &origin, const vec3 &axis, double theta, bool degrees)
Builds a rotational matrix about an arbitrary axis.
Definition: geometry.cpp:202
static void err(const std::string &feature, const Args &... args)
Definition: logger.h:68
void check_matrices(const GEO::Matrix< 4, double > &lhs, const GEO::Matrix< 4, double > &rhs)
static void out(const std::string &feature, const Args &... args)
Definition: logger.h:61
void check_vertex(const vec3 &in, const vec3 &result)
void test_translate(GeoModel3D &geomodel)
const std::string & category() const
Definition: common.h:165
Classes to build GeoModel from various inputs.
Definition: algorithm.h:48
This template is a specialization of a gme_id to the GeoModelMeshEntity.
Definition: entity_type.h:285
void RINGMESH_API default_configure()
Definition: common.cpp:99
void test_rotation_matrix()