About the libGeom (tutorial)

Tutorials

basic
your first simulation
advanced

This page describes the usage of libGeom classes

This tutorial is about the main classes of the libGeom : the Vector class, the Point class, the Quaternion class and the Frame class.

All is frame

The euclidean geometrical entities Vector, Point and Quaternion are expressed in a given frame. Some geometrical computations are very difficult to write (and read) when using uniquely a global frame. The frame management is a very powerful feature that allows us to write these geometrical operations in local frames. To express a Vector, a Point or a Quaternion in a local frame, you must pass this local frame as parameter of these object constructors. Note that :

  • an item can’t change its reference frame.
  • the operations between entities that are expressed in different frames are not allowed.
  • the changing frame operations can be done through constructors.

To build a new frame, you need a Point, that models its center and a Quaternion, that models its orientation. The code snippet below highlights some feature of these geometrical entities.

// include the right headers 
#include "GranOO3/Geom/Vector.hpp"
#include "GranOO3/Geom/Point.hpp"
#include "GranOO3/Geom/Quaternion.hpp"
#include "GranOO3/Geom/Frame.hpp"
#include "GranOO3/Geom/Constant.hpp"

// and use namespace for avoiding writing GranOO3 everywhere 
using namespace GranOO3;
...

// Get the global frame
const Geom::Frame& f0 = Geom::global::frame;
  
// Build a frame
Geom::Point      p (0., 1., 0.);
Geom::Quaternion q (0., 0., 0., 1.);
Geom::Frame      f(p, q, f0);
  
// Build a vector expressed in the global frame
Geom::Vector v1(0.,0.,0.);
  
// Express this vector in the Frame "f" thanks to the copy constructor
Geom::Vector v2(v1, f0, f);
  
// And See the result !
std::cout << v2 << std::endl;
  
// Be aware, v1 and v2 are not expressed in the same frame
// it make no sense to add two vectors expressed in different frame
Geom::Vector v3 = v1 + v2; // MISTAKE !
import granoo3.lib as granoo

# get global frame
f0 =  granoo.global_frame

# build a frame
p = granoo.point(0., 1., 0.)
q = granoo.quaternion(0., 0., 0., 1.)
f = granoo.frame(p, q, f0)
 
# build a vector expressed in the global frame
v1 = granoo.vector(0.,0.,0.)
 
# express this vector in the Frame "f" thanks to the copy constructor
v2 = granoo.vector(v1, f0, f)

# and see the result !
print ('v2=', v2) 

# Be aware, v1 and v2 are not expressed in the same frame
# it make no sense to add two vectors expressed in different frame
v3 = v1 + v2 # MISTAKE !

You must be aware, changing frame operations are not obvious, you must remember in which frame your geom entities are expressed.

A point is not a vector

These two classes are quiet similar. However these two concepts are different. If you take a Point and a Vector with the same coordinate values, the changing frame operation will not give you the same result. In addition, mathematical operations, such as subtraction, cross product, etc… are not allowed with Point.

Under certain conditions, you need to consider a Point as a Vector. To do that, you can use the Point to Vector casting and vice versa as follows.

// Build a point 
Geom::Point p(1., 2., 3.);
 
// Cast it to a point
Geom::Vector & v = p.to_vector();
 
// Translate the given vector
Geom::Vector trans(1., 0., 0.);
v += trans; 
 
// See the result on the point
std::cout << p << std::endl; // You translate the point too !
import granoo3.lib as granoo

# build a point 
p = granoo.point(1., 2., 3.)
 
# cast it to a point
v = p.to_vector()
 
# translate the given vector
trans = granoo.vector(1., 0., 0.)
v += trans 
 
# see the result on the point
print ("p=", p)  # You translate the point too !

About quaternion

Quaternions are used to express attitudes, angular velocities or angular accelerations. If you are not clear about the Quaternion concept, you can read the last part of the book Discrete Element Workbench for Highly Dynamic Thermo-mechanical Analysis: GranOO. This book explains step by step this advanced concept. The following example shows how to impose a rotation of pi/2 along the X axis to a vector.

// Get the global frame
const Geom::Frame& f0 = Geom::global::frame;

// build a new frame 
Geom::Point      p (0., 1., 0.);
Geom::Quaternion q (0., 0., 0., 1.);
Geom::Frame      f(p, q, f0);

// Get the X axis of the global frame
const Geom::Vector& X = Geom::axis::x;
  
// Rotate the frame to a pi/2 angle along X
q.set_axis_angle(X, M_PI/2.);

// The vector v is expressed in the Frame "f" 
Geom::Vector v(1.,0.,0);

// New we get its value in the global frame
std::cout << Geom::Vector(v, f, f0) << std::endl;
import granoo3.lib as granoo
import math

# get global frame
f0 =  granoo.global_frame

# build a frame
p = granoo.point(0., 1., 0.)
q = granoo.quaternion(0., 0., 0., 1.)
f = granoo.frame(p, q, f0)

# get the X axis of the global frame
X = granoo.x_axis
  
# rotate the frame to a pi/2 angle along X
q.set_axis_angle(X, math.pi/2.)

# we suppose that this vector v is expressed in the Frame "f" 
v = granoo.vector(1.,0.,0)

# new we get its value in the global frame
v_glob = granoo.vector(v, f, f0)
print ('v_glob=', v_glob)