/// Determines the Hermann-Mauguin symbol of the rotation-, rotoinversion- or /// screw-axis. std::string SymmetryElementRotationGenerator::determineSymbol( const SymmetryOperation &operation) const { const Kernel::IntMatrix &matrix = operation.matrix(); int trace = matrix.Trace(); int determinant = matrix.determinant(); if (trace == 0 && determinant == -1) { return "-3"; } std::string symbol; if (determinant < 0) { symbol += "-"; } symbol += boost::lexical_cast<std::string>(operation.order()); int translation = static_cast<int>(static_cast<double>(operation.order()) * Kernel::V3D(determineTranslation(operation)).norm()); if (translation != 0) { symbol += boost::lexical_cast<std::string>(translation); } return symbol; }
/** * Transforms the operation using the internally stored SymmetryOperation. * * This method returns the transformed symmetry operation, using the * following relation: * * S' = O^-1 * S * O * * Where O is the internally stored operation. * * @param operation :: SymmetryOperation to transform. * @return Transformed symmetry operation. */ SymmetryOperation GroupTransformation::transformOperation( const SymmetryOperation &operation) const { MatrixVectorPair<double, V3R> op = m_inversePair * MatrixVectorPair<double, V3R>(convertMatrix<double>(operation.matrix()), operation.vector()) * m_matrixVectorPair; return SymmetryOperation(op.getMatrix(), op.getVector()); }
/// Returns a vector with all symmetry operations that are part of the cyclic /// group defined by the generating operation. std::vector<SymmetryOperation> CyclicGroup::generateAllOperations(const SymmetryOperation &operation) const { std::vector<SymmetryOperation> symOps(1, operation); symOps.reserve(operation.order()); for (size_t i = 1; i < operation.order(); ++i) { symOps.push_back(operation * symOps.back()); } return symOps; }
/// Checks the trace and determinat of the matrix to determine if the matrix /// belongs to a rotation. bool SymmetryElementRotationGenerator::canProcess( const SymmetryOperation &operation) const { const Kernel::IntMatrix &matrix = operation.matrix(); int determinant = matrix.determinant(); int trace = matrix.Trace(); return (abs(trace) != 3) && !(trace == 1 && determinant == -1); }
/// Generates an instance of SymmetryElementMirror with the corresponding /// symbol, axis and translation vector. SymmetryElement_sptr SymmetryElementMirrorGenerator::generateElement( const SymmetryOperation &operation) const { const Kernel::IntMatrix &matrix = operation.matrix(); V3R axis = determineAxis(matrix); V3R translation = determineTranslation(operation); std::string symbol = determineSymbol(operation); return boost::make_shared<SymmetryElementMirror>(symbol, axis, translation); }
/** * Creates a SymmetryElement from a SymmetryOperation * * As detailed in the class description, the method checks whether there is * already a prototype SymmetryElement for the provided SymmetryOperation. If * not, it tries to find an appropriate generator and uses that to create * the prototype. Then it returns a clone of the prototype. * * @param operation :: SymmetryOperation for which to generate the element. * @return SymmetryElement for the supplied operation. */ SymmetryElement_sptr SymmetryElementFactoryImpl::createSymElement( const SymmetryOperation &operation) { std::string operationIdentifier = operation.identifier(); SymmetryElement_sptr element = createFromPrototype(operationIdentifier); if (element) { return element; } AbstractSymmetryElementGenerator_sptr generator = getGenerator(operation); if (!generator) { throw std::runtime_error("Could not process symmetry operation '" + operationIdentifier + "'."); } insertPrototype(operationIdentifier, generator->generateElement(operation)); return createFromPrototype(operationIdentifier); }
/// Determines the rotation sense according to the description in ITA 11.2. SymmetryElementRotation::RotationSense SymmetryElementRotationGenerator::determineRotationSense( const SymmetryOperation &operation, const V3R &rotationAxis) const { Kernel::V3D pointOnAxis1 = rotationAxis; Kernel::V3D pointOnAxis2 = rotationAxis * 2; Kernel::V3D pointOffAxis = rotationAxis + Kernel::V3D(2.1, 5.05, -1.1); Kernel::V3D generatedPoint = operation * pointOffAxis; Kernel::DblMatrix matrix(3, 3, false); matrix.setColumn(0, pointOnAxis2 - pointOnAxis1); matrix.setColumn(1, pointOffAxis - pointOnAxis1); matrix.setColumn(2, generatedPoint - pointOnAxis1); double determinant = matrix.determinant() * operation.matrix().determinant(); if (determinant < 0) { return SymmetryElementRotation::Negative; } else { return SymmetryElementRotation::Positive; } }
/// Returns the reduced vector of the operation. V3R SymmetryElementWithAxisGenerator::determineTranslation( const SymmetryOperation &operation) const { return operation.reducedVector(); }
/// Checks that the trace of the matrix is 1 and the determinant is -1. bool SymmetryElementMirrorGenerator::canProcess( const SymmetryOperation &operation) const { const Kernel::IntMatrix &matrix = operation.matrix(); return matrix.Trace() == 1 && matrix.determinant() == -1; }