/*
* 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);
}