/*! \file pointgroups.h * \brief Quaternion-represented 3D point groups. */ #ifndef POINTGROUPS_H #define POINTGROUPS_H #ifdef __cplusplus extern "C" { #endif #include "qpms_error.h" #include "quaternions.h" /// Returns true if the point group class belongs to one of the seven "axial" group series. static inline _Bool qpms_pg_is_finite_axial(qpms_pointgroup_class cls) { switch(cls) { case QPMS_PGS_CN: case QPMS_PGS_S2N: case QPMS_PGS_CNH: case QPMS_PGS_CNV: case QPMS_PGS_DN: case QPMS_PGS_DND: case QPMS_PGS_DNH: return 1; default: return 0; } } /// Absolute tolerance threshold used internally to consider two different `qpms_irot3_t` instances equal. /** * Used by @ref qpms_pg_irot3_approx_cmp_v. * By default, set to @ref QPMS_QUAT_ATOL. * It should work fine if the point group orders stay reasonable (thousands or less). * Do not touch if unsure what you are doing. */ extern double qpms_pg_quat_cmp_atol; /// An ordering of qpms_irot3_t that considers close enough elements equal. int qpms_pg_irot3_approx_cmp(const qpms_irot3_t *, const qpms_irot3_t *, double atol ///< Absolute tolerance for the quaternion part difference. ); /// A `search.h` compatible ordering of qpms_irot3_t that considers close enough elements equal. /** The tolerance is determined by global variable @ref qpms_pg_quat_cmp_atol. */ int qpms_pg_irot3_approx_cmp_v(const void *, const void *); /// Returns the order of a given 3D point group type. /** For infinite groups returns 0. */ qpms_gmi_t qpms_pg_order(qpms_pointgroup_class cls, ///< Point group class. qpms_gmi_t n ///< Number of rotations around main axis (only for finite axial groups). ); /// Generates the canonical elements of a given 3D point group type. /** Uses the canonical generators and DPS. */ qpms_irot3_t *qpms_pg_canonical_elems( qpms_irot3_t *target, ///< Target array (optional; if NULL, a new one is allocated) qpms_pointgroup_class cls, ///< Point group class. qpms_gmi_t ///< Number of rotations around \a z axis (only for axial group classes). ); /// Returns the number of canonical generators of a given 3D point group type. /** TODO what does it do for infinite (Lie) groups? */ qpms_gmi_t qpms_pg_genset_size(qpms_pointgroup_class cls, ///< Point group class. qpms_gmi_t n ///< Number of rotations around main axis (only for axial groups). ); /// Fills an array of canonical generators of a given 3D point group type. /** TODO what does it do for infinite (Lie) groups? */ qpms_gmi_t qpms_pg_genset(qpms_pointgroup_class cls, ///< Point group class. qpms_gmi_t n, ///< Number of rotations around main axis (only for axial groups). qpms_irot3_t gen[] ///< Target generator array ); /// Generates all elements of a given point group. /** The order of elements corresponds to the one obtained from qpms_pg_canonical_elems(). */ qpms_irot3_t *qpms_pg_elems(qpms_irot3_t *target, ///< Target array (optional; if NULL, a new one is allocated) qpms_pointgroup_t g ///< Specification of the point group. ); /// Checks whether \a a is subgroup of \a b (in a dirty general way). _Bool qpms_pg_is_subgroup(qpms_pointgroup_t a, qpms_pointgroup_t b); #ifdef __cplusplus } #endif #endif //POINTGROUPS_H