// -*- C++ -*-
/*
* Gnome Chemistry Utils
* atom.cc
*
* Copyright (C) 2001-2005 Jean Bréfort <jean.brefort@normalesup.org>
*
* This program 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.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
* USA
*/
#include "element.h"
#include "atom.h"
#include "bond.h"
#include "xml-utils.h"
#include <cmath>
#include <cstring>
using namespace gcu;
Atom::Atom(): Object(AtomType)
{
m_Z = 0;
m_x = m_y = m_z = 0.0;
m_Charge = 0;
}
Atom::~Atom()
{
m_Bonds.clear();
}
Atom::Atom(int Z, double x, double y, double z): Object(AtomType)
{
SetZ(Z);
m_x = x;
m_y = y;
m_z = z;
m_Charge = 0;
}
Atom::Atom(Atom& a): Object(AtomType)
{
SetZ(a.m_Z);
m_x = a.m_x;
m_y = a.m_y;
m_z = a.m_z;
m_Charge = a.m_Charge;
}
Atom& Atom::operator=(Atom& a)
{
SetZ(a.m_Z);
m_x = a.m_x;
m_y = a.m_y;
m_z = a.m_z;
m_Charge = a.m_Charge;
return *this ;
}
void Atom::SetZ(int Z)
{
m_Z = Z;
}
double Atom::Distance(Atom* pAtom)
{
return sqrt(square(m_x - pAtom->m_x) + square(m_y - pAtom->m_y) + square(m_z - pAtom->m_z));
}
void Atom::zoom(double ZoomFactor)
{
m_x *= ZoomFactor;
m_y *= ZoomFactor;
m_z *= ZoomFactor;
}
bool Atom::GetCoords(double *x, double *y, double *z)
{
if (!x || !y) return false;
*x = m_x;
*y = m_y;
if (z) *z = m_z;
return true;
}
const gchar* Atom::GetSymbol()
{
Element* Elt = Element::GetElement(m_Z);
return (Elt)? Element::Symbol(m_Z): NULL;
}
void Atom::AddBond(Bond* pBond)
{
m_Bonds[pBond->GetAtom(this)] = pBond;
}
void Atom::RemoveBond(Bond* pBond)
{
m_Bonds.erase(pBond->GetAtom(this));
}
Bond* Atom::GetFirstBond(map<Atom*, Bond*>::iterator& i)
{
i = m_Bonds.begin();
if (i == m_Bonds.end()) return NULL;
return (*i).second;
}
Bond* Atom::GetNextBond(map<Atom*, Bond*>::iterator& i)
{
i++;
if (i == m_Bonds.end()) return NULL;
return (*i).second;
}
void Atom::Move(double x, double y, double z)
{
m_x += x;
m_y += y;
m_z += z;
}
void Atom::Transform2D(Matrix2D& m, double x, double y)
{
m_x -= x;
m_y -= y;
m.Transform (m_x, m_y);
m_x += x;
m_y += y;
}
xmlNodePtr Atom::Save(xmlDocPtr xml)
{
xmlNodePtr parent;
gchar buf[16];
parent = xmlNewDocNode(xml, NULL, (xmlChar*)"atom", NULL);
if (!parent) return NULL;
SaveId(parent);
if (m_Z) {
strncpy(buf, GetSymbol(), sizeof(buf));
xmlNewProp(parent, (xmlChar*)"element", (xmlChar*)buf);
}
if (m_Charge)
{
snprintf(buf, sizeof(buf), "%d", m_Charge);
xmlNewProp(parent, (xmlChar*)"charge", (xmlChar*)buf);
}
if (!WritePosition(xml, parent, NULL, m_x, m_y, m_z)) {xmlFreeNode(parent); return NULL;}
if (!SaveNode(xml, parent)) {xmlFreeNode(parent); return NULL;}
return parent;
}
bool Atom::Load (xmlNodePtr node)
{
char* tmp;
tmp = (char*) xmlGetProp (node, (xmlChar*) "id");
if (tmp) {
SetId (tmp);
xmlFree (tmp);
}
tmp = (char*) xmlGetProp (node, (xmlChar*) "element");
if (tmp) {
m_Z = Element::Z(tmp); //Don't check if element exists. Applications that do not accept unknown elements should check
xmlFree (tmp);
}
tmp = (char*) xmlGetProp (node, (xmlChar*) "charge");
if (tmp) {
m_Charge = (char) atoi (tmp);
xmlFree (tmp);
} else
m_Charge = 0;
if (!ReadPosition (node, NULL, &m_x, &m_y, &m_z) || (!LoadNode (node)))
return false;
return true;
}
bool Atom::LoadNode(xmlNodePtr node)
{
return true;
}
bool Atom::SaveNode(xmlDocPtr xml, xmlNodePtr node)
{
return true;
}
Bond* Atom::GetBond(Atom* pAtom)
{
Bond* pBond = m_Bonds[pAtom];
if (!pBond) m_Bonds.erase(pAtom);
return pBond;
}
syntax highlighted by Code2HTML, v. 0.9.1