85 lines
3.2 KiB
C
85 lines
3.2 KiB
C
/*! \file pointgroups.h
|
|
* \brief Quaternion-represented 3D point groups.
|
|
*/
|
|
#ifndef POINTGROUPS_H
|
|
#define POINTGROUPS_H
|
|
|
|
#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 true;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/// 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);
|
|
|
|
|
|
|
|
#endif //POINTGROUPS_H
|