/* * Copyright (C) 2010 Thorsten Liebig (Thorsten.Liebig@gmx.de) * * This program 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 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "ParameterCoord.h" #include "tinyxml.h" #include double* TransformCoordSystem(const double* inCoord, double* out, CoordinateSystem CS_In, CoordinateSystem CS_out) { double in[3] = {inCoord[0],inCoord[1],inCoord[2]}; switch (CS_In) { case CARTESIAN: //input coords are cartesian switch (CS_out) { default: //unknown transform --> just copy case CARTESIAN: // transform cartesian --> cartesian for (int n=0;n<3;++n) out[n] = in[n]; //just copy break; case CYLINDRICAL: // transform cartesian --> cylindrical out[0] = sqrt(in[0]*in[0]+in[1]*in[1]); // r = sqrt(x²+y²) out[1] = atan2(in[1],in[0]); //alpha = atan2(y,x) out[2] = in[2]; //z==z break; } break; case CYLINDRICAL: //input coords are cylindrical switch (CS_out) { case CARTESIAN: // transform cylindrical --> cartesian out[0] = in[0] * cos(in[1]); // x = r * cos(alpha) out[1] = in[0] * sin(in[1]); // y = r * sin(alpha) out[2] = in[2]; // z = z break; default: //unknown transform --> just copy case CYLINDRICAL: // transform cylindrical --> cylindrical for (int n=0;n<3;++n) out[n] = in[n]; //just copy break; } break; default: //unknown transform --> just copy for (int n=0;n<3;++n) out[n] = in[n]; //just copy } return out; } ParameterCoord::ParameterCoord() { m_CoordSystem = UNDEFINED_CS; for (int n=0;n<3;++n) m_Coords[n] = new ParameterScalar(); Update(); } ParameterCoord::ParameterCoord(ParameterSet* ParaSet) { m_CoordSystem = UNDEFINED_CS; for (int n=0;n<3;++n) m_Coords[n] = new ParameterScalar(ParaSet,0); Update(); } ParameterCoord::ParameterCoord(CoordinateSystem cs) { m_CoordSystem = cs; for (int n=0;n<3;++n) m_Coords[n] = new ParameterScalar(); Update(); } ParameterCoord::ParameterCoord(ParameterSet* ParaSet, const double value[3]) { m_CoordSystem = UNDEFINED_CS; for (int n=0;n<3;++n) m_Coords[n] = new ParameterScalar(ParaSet, value[n]); Update(); } ParameterCoord::ParameterCoord(ParameterSet* ParaSet, const std::string value[3]) { m_CoordSystem = UNDEFINED_CS; for (int n=0;n<3;++n) m_Coords[n] = new ParameterScalar(ParaSet, value[n]); Update(); } ParameterCoord::ParameterCoord(ParameterCoord* pc) { m_CoordSystem = UNDEFINED_CS; for (int n=0;n<3;++n) m_Coords[n]=NULL; Copy(pc); } ParameterCoord::~ParameterCoord() { for (int n=0;n<3;++n) { delete m_Coords[n]; m_Coords[n]=NULL; } } void ParameterCoord::SetParameterSet(ParameterSet *paraSet) { for (int n=0;n<3;++n) m_Coords[n]->SetParameterSet(paraSet); Update(); } void ParameterCoord::SetCoordinateSystem(CoordinateSystem cs, CoordinateSystem fallBack_cs) { if (cs!=UNDEFINED_CS) return SetCoordinateSystem(cs); return SetCoordinateSystem(fallBack_cs); } int ParameterCoord::SetValue(int ny, std::string value) { if ((ny<0) || (ny>2)) return -1; int EC = m_Coords[ny]->SetValue(value); Update(); return EC; } void ParameterCoord::SetValue(int ny, double value) { if ((ny<0) || (ny>2)) return; m_Coords[ny]->SetValue(value); Update(); } double ParameterCoord::GetValue(int ny) { if ((ny<0) || (ny>2)) return nan(""); return m_Coords[ny]->GetValue(); } const std::string ParameterCoord::GetValueString(int ny) const { if ((ny<0) || (ny>2)) return "nan"; return m_Coords[ny]->GetValueString(); } double ParameterCoord::GetCoordValue(int ny, CoordinateSystem cs) { if ((ny<0) || (ny>2)) return nan(""); return GetCoords(cs)[ny]; } ParameterScalar* ParameterCoord::GetCoordPS(int ny) { if ((ny>=0) && (ny<3)) return m_Coords[ny]; return 0; } const double* ParameterCoord::GetNativeCoords() const { switch (m_CoordSystem) { default: case CARTESIAN: return GetCartesianCoords(); case CYLINDRICAL: return GetCylindricalCoords(); } return NULL; //this should not happen... } const double* ParameterCoord::GetCoords(CoordinateSystem cs) const { switch (cs) { case CARTESIAN: return GetCartesianCoords(); case CYLINDRICAL: return GetCylindricalCoords(); default: return GetNativeCoords(); } } bool ParameterCoord::Evaluate(std::string *ErrStr) { int EC=0; bool bOK=true; for (int i=0;i<3;++i) { EC=m_Coords[i]->Evaluate(); if (EC!=ParameterScalar::NO_ERROR) bOK=false; if ((EC!=ParameterScalar::NO_ERROR) && (ErrStr!=NULL)) { std::stringstream stream; stream << std::endl << "Error in ParameterCoord (component: " << i << "): "; ErrStr->append(stream.str()); PSErrorCode2Msg(EC,ErrStr); } } return bOK; } void ParameterCoord::Copy(ParameterCoord* pc) { m_CoordSystem = pc->m_CoordSystem; for (int n=0;n<3;++n) { delete m_Coords[n]; m_Coords[n] = new ParameterScalar(pc->m_Coords[n]); } Update(); } void ParameterCoord::Update() { double coords[3] = {m_Coords[0]->GetValue(),m_Coords[1]->GetValue(),m_Coords[2]->GetValue()}; TransformCoordSystem(coords, m_CartesianCoords, m_CoordSystem, CARTESIAN); TransformCoordSystem(coords, m_CylindricalCoords, m_CoordSystem, CYLINDRICAL); } bool ParameterCoord::Write2XML(TiXmlElement *elem, bool parameterised) { if (elem==NULL) return false; WriteTerm(*m_Coords[0],*elem,"X",parameterised); WriteTerm(*m_Coords[1],*elem,"Y",parameterised); WriteTerm(*m_Coords[2],*elem,"Z",parameterised); return true; } bool ParameterCoord::ReadFromXML(TiXmlElement *elem) { if (elem==NULL) return false; if (ReadTerm(*m_Coords[0],*elem,"X")==false) return false; if (ReadTerm(*m_Coords[1],*elem,"Y")==false) return false; if (ReadTerm(*m_Coords[2],*elem,"Z")==false) return false; return true; }