Select Git revision
export_entity_to_density.cc
connector_impl.cc 3.59 KiB
//------------------------------------------------------------------------------
// This file is part of the OpenStructure project <www.openstructure.org>
//
// Copyright (C) 2008-2010 by the OpenStructure authors
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License as published by the Free
// Software Foundation; either version 3.0 of the License, or (at your option)
// any later version.
// This library 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 Lesser General Public License for more
// details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this library; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//------------------------------------------------------------------------------
#include <cmath>
#include <ost/log.hh>
#include "connector_impl.hh"
#include "atom_impl.hh"
#include "entity_impl.hh"
#include <ost/mol/entity_visitor.hh>
namespace ost { namespace mol { namespace impl {
ConnectorImpl::ConnectorImpl(const EntityImplPtr& e, const AtomImplPtr& first,
const AtomImplPtr& second,
Real l, Real t, Real p, unsigned char bond_order):
first_(first),
second_(second),
len_(l),
bond_order_(bond_order)
{}
void ConnectorImpl::Apply(EntityVisitor& v)
{
LOGN_TRACE("visitor @" << &v << " visiting bond impl @" << this);
v.VisitBond(BondHandle(shared_from_this()));
}
ConnectorImpl::~ConnectorImpl() {
}
namespace {
// this function finds the rotation matrix that rotates the positive z axis
// onto the given vector. it is assumed that the vector has unit length.
geom::Mat3 find_rotation(const geom::Vec3& d) {
// assume the vectors are already normalized
if (std::abs(Real(1.0-Length(d)))>0.00001) {
LOGN_DEBUG("connector find_rotation() has faulty length: " << Length(d));
assert(0 && "error is big");
}
Real dot=d[2];
if (dot<-0.999999) {
return geom::Mat3(-1, 0, 0,
0, 1, 0,
0, 0,-1);
} else if (dot>0.999999) {
return geom::Mat3();
} else {
geom::Vec3 c=Normalize(geom::Cross(geom::Vec3(0,0,1), d));
geom::Vec3 v=Normalize(geom::Cross(c, d));
geom::Mat3 mat(v[0], c[0], d[0],
v[1], c[1], d[1],
v[2], c[2], d[2]);
return mat;
}
}
}
geom::Vec3 ConnectorImpl::GetPos() const
{
return (GetFirst()->GetPos()+GetSecond()->GetPos())*0.5;
}
Real ConnectorImpl::GetLength() const
{
Real length;
if (this->GetFirst()->GetEntity()->HasICS()==false) {
length=geom::Distance(this->GetFirst()->GetOriginalPos(),this->GetSecond()->GetOriginalPos());
} else {
length=len_;
}
return length;
}
void ConnectorImpl::SetDir(const geom::Vec3& dir) {
geom::Vec3 v=Normalize(dir);
local_rot_=find_rotation(v);
}
void ConnectorImpl::SetDirAndLength(const geom::Vec3& dir) {
len_=Length(dir);
geom::Vec3 v=dir/len_;
local_rot_=find_rotation(v);
}
bool ConnectorImpl::IsConnectorOf(const AtomImplPtr& a,
const AtomImplPtr& b) const {
return ((first_.lock()==a && second_.lock()==b) ||
(first_.lock()==b && second_.lock()==a));
}
geom::Vec3 ConnectorImpl::GetOriginalPos() const
{
return (this->GetFirst()->GetOriginalPos()+
this->GetSecond()->GetOriginalPos())*0.5;
}
void ConnectorImpl::Switch()
{
first_.swap(second_);
}
}}} // ns