/* * Project: MoleCuilder * Description: creates and alters molecular systems * Copyright (C) 2014 Frederik Heber. All rights reserved. * * * This file is part of MoleCuilder. * * MoleCuilder is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * MoleCuilder is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with MoleCuilder. If not, see . */ /* * SurfaceRandomInserter.cpp * * Created on: Sep 03, 2014 * Author: heber */ // include config.h #ifdef HAVE_CONFIG_H #include #endif #include "CodePatterns/MemDebug.hpp" #include "SurfaceRandomInserter.hpp" #include "Atom/atom.hpp" #include "CodePatterns/Log.hpp" #include "LinearAlgebra/RealSpaceMatrix.hpp" #include "LinearAlgebra/Vector.hpp" #include "Shapes/Shape.hpp" /** Constructor for class SurfaceRandomInserter. * * @param _s shape on whose surface the insertion nodes lie * @param _alignedAxis axis along which to be inserted cluster is aligned to * @param _MaxAtomComponent maximum component for random atom translations * @param _MaxMoleculeComponent maximum component for random molecule translations */ SurfaceRandomInserter::SurfaceRandomInserter( const Shape & _s, const Vector &_alignedAxis, const double _MaxAtomComponent, const double _MaxMoleculeComponent) : RandomInserter(_MaxAtomComponent, _MaxMoleculeComponent, false), shape(_s), alignedAxis(_alignedAxis.getNormalized()) {} /** Destructor for class SurfaceRandomInserter. * */ SurfaceRandomInserter::~SurfaceRandomInserter() {} /** Inserter operator that rotates the cluster to be perpendicular on surface at * desired \a offset and translates it there. * * \note We assume that cluster is aligned along \a SurfaceRandomInserter::alignedAxis and * the translation is done relative to origin. * * @param offset * @return always true */ bool SurfaceRandomInserter::operator()(ClusterInterface::Cluster_impl cluster, const Vector &offset) const { // create rotation matrix, assuming cluster is aligned along z axis Vector SurfaceNormal = shape.getNormal(offset); // get normal at desired point LOG(3, "DEBUG: Normal vector at " << offset << " is " << SurfaceNormal << "."); const double alpha = - alignedAxis.Angle(SurfaceNormal); // we have to rotate back LOG(4, "DEBUG: Rotation angle is " << alpha << "."); SurfaceNormal.VectorProduct(alignedAxis); // get the rotation axis as normal direction to both RealSpaceMatrix M; if (!SurfaceNormal.IsZero()) { SurfaceNormal.Normalize(); LOG(4, "DEBUG: Rotation axis is " << SurfaceNormal << "."); M.setRotation(SurfaceNormal, alpha); } else { M.setIdentity(); } // rotate cluster cluster->transform(M); // translate return RandomInserter::operator()(cluster, offset); }