/*
* Project: MoleCuilder
* Description: creates and alters molecular systems
* Copyright (C) 2012 University of Bonn. 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 .
*/
/*
* SurfaceInserter.cpp
*
* Created on: Apr 03, 2012
* Author: heber
*/
// include config.h
#ifdef HAVE_CONFIG_H
#include
#endif
//#include "CodePatterns/MemDebug.hpp"
#include "SurfaceInserter.hpp"
#include "Atom/atom.hpp"
#include "CodePatterns/Log.hpp"
#include "LinearAlgebra/RealSpaceMatrix.hpp"
#include "LinearAlgebra/Vector.hpp"
#include "Shapes/Shape.hpp"
/** Constructor for class SurfaceInserter.
*
* @param _s shape on whose surface the insertion nodes lie
* @param _alignedAxis axis along which to be inserted cluster is aligned to
*/
SurfaceInserter::SurfaceInserter(const Shape & _s, const Vector &_alignedAxis) :
shape(_s),
alignedAxis(_alignedAxis.getNormalized())
{}
/** Destructor for class SurfaceInserter.
*
*/
SurfaceInserter::~SurfaceInserter()
{}
/** 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 SurfaceInserter::alignedAxis and
* the translation is done relative to origin.
*
* @param offset
* @return always true
*/
bool SurfaceInserter::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
SurfaceNormal.Normalize();
LOG(4, "DEBUG: Rotation axis is " << SurfaceNormal << ".");
RealSpaceMatrix M;
M.setRotation(SurfaceNormal, alpha);
// rotate cluster
cluster->transform(M);
// translate
cluster->translate(offset);
return true;
}