1 /*
2 * Copyright (C) 2010 Thorsten Liebig (Thorsten.Liebig@gmx.de)
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published
6 * by the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 #include "ParameterCoord.h"
19 #include "tinyxml.h"
20 #include <sstream>
21
TransformCoordSystem(const double * inCoord,double * out,CoordinateSystem CS_In,CoordinateSystem CS_out)22 double* TransformCoordSystem(const double* inCoord, double* out, CoordinateSystem CS_In, CoordinateSystem CS_out)
23 {
24 double in[3] = {inCoord[0],inCoord[1],inCoord[2]};
25 switch (CS_In)
26 {
27 case CARTESIAN: //input coords are cartesian
28 switch (CS_out)
29 {
30 default: //unknown transform --> just copy
31 case CARTESIAN: // transform cartesian --> cartesian
32 for (int n=0;n<3;++n)
33 out[n] = in[n]; //just copy
34 break;
35 case CYLINDRICAL: // transform cartesian --> cylindrical
36 out[0] = sqrt(in[0]*in[0]+in[1]*in[1]); // r = sqrt(x²+y²)
37 out[1] = atan2(in[1],in[0]); //alpha = atan2(y,x)
38 out[2] = in[2]; //z==z
39 break;
40 }
41 break;
42 case CYLINDRICAL: //input coords are cylindrical
43 switch (CS_out)
44 {
45 case CARTESIAN: // transform cylindrical --> cartesian
46 out[0] = in[0] * cos(in[1]); // x = r * cos(alpha)
47 out[1] = in[0] * sin(in[1]); // y = r * sin(alpha)
48 out[2] = in[2]; // z = z
49 break;
50 default: //unknown transform --> just copy
51 case CYLINDRICAL: // transform cylindrical --> cylindrical
52 for (int n=0;n<3;++n)
53 out[n] = in[n]; //just copy
54 break;
55 }
56 break;
57 default: //unknown transform --> just copy
58 for (int n=0;n<3;++n)
59 out[n] = in[n]; //just copy
60 }
61 return out;
62 }
63
ParameterCoord()64 ParameterCoord::ParameterCoord()
65 {
66 m_CoordSystem = UNDEFINED_CS;
67 for (int n=0;n<3;++n)
68 m_Coords[n] = new ParameterScalar();
69 Update();
70 }
71
ParameterCoord(ParameterSet * ParaSet)72 ParameterCoord::ParameterCoord(ParameterSet* ParaSet)
73 {
74 m_CoordSystem = UNDEFINED_CS;
75 for (int n=0;n<3;++n)
76 m_Coords[n] = new ParameterScalar(ParaSet,0);
77 Update();
78 }
79
ParameterCoord(CoordinateSystem cs)80 ParameterCoord::ParameterCoord(CoordinateSystem cs)
81 {
82 m_CoordSystem = cs;
83 for (int n=0;n<3;++n)
84 m_Coords[n] = new ParameterScalar();
85 Update();
86 }
87
ParameterCoord(ParameterSet * ParaSet,const double value[3])88 ParameterCoord::ParameterCoord(ParameterSet* ParaSet, const double value[3])
89 {
90 m_CoordSystem = UNDEFINED_CS;
91 for (int n=0;n<3;++n)
92 m_Coords[n] = new ParameterScalar(ParaSet, value[n]);
93 Update();
94 }
95
ParameterCoord(ParameterSet * ParaSet,const std::string value[3])96 ParameterCoord::ParameterCoord(ParameterSet* ParaSet, const std::string value[3])
97 {
98 m_CoordSystem = UNDEFINED_CS;
99 for (int n=0;n<3;++n)
100 m_Coords[n] = new ParameterScalar(ParaSet, value[n]);
101 Update();
102 }
103
ParameterCoord(ParameterCoord * pc)104 ParameterCoord::ParameterCoord(ParameterCoord* pc)
105 {
106 m_CoordSystem = UNDEFINED_CS;
107 for (int n=0;n<3;++n)
108 m_Coords[n]=NULL;
109 Copy(pc);
110 }
111
~ParameterCoord()112 ParameterCoord::~ParameterCoord()
113 {
114 for (int n=0;n<3;++n)
115 {
116 delete m_Coords[n];
117 m_Coords[n]=NULL;
118 }
119 }
120
SetParameterSet(ParameterSet * paraSet)121 void ParameterCoord::SetParameterSet(ParameterSet *paraSet)
122 {
123 for (int n=0;n<3;++n)
124 m_Coords[n]->SetParameterSet(paraSet);
125 Update();
126 }
127
SetCoordinateSystem(CoordinateSystem cs,CoordinateSystem fallBack_cs)128 void ParameterCoord::SetCoordinateSystem(CoordinateSystem cs, CoordinateSystem fallBack_cs)
129 {
130 if (cs!=UNDEFINED_CS)
131 return SetCoordinateSystem(cs);
132 return SetCoordinateSystem(fallBack_cs);
133 }
134
SetValue(int ny,std::string value)135 int ParameterCoord::SetValue(int ny, std::string value)
136 {
137 if ((ny<0) || (ny>2))
138 return -1;
139 int EC = m_Coords[ny]->SetValue(value);
140 Update();
141 return EC;
142 }
143
SetValue(int ny,double value)144 void ParameterCoord::SetValue(int ny, double value)
145 {
146 if ((ny<0) || (ny>2))
147 return;
148 m_Coords[ny]->SetValue(value);
149 Update();
150 }
151
GetValue(int ny)152 double ParameterCoord::GetValue(int ny)
153 {
154 if ((ny<0) || (ny>2))
155 return nan("");
156 return m_Coords[ny]->GetValue();
157 }
158
GetValueString(int ny) const159 const std::string ParameterCoord::GetValueString(int ny) const
160 {
161 if ((ny<0) || (ny>2))
162 return "nan";
163 return m_Coords[ny]->GetValueString();
164 }
165
GetCoordValue(int ny,CoordinateSystem cs)166 double ParameterCoord::GetCoordValue(int ny, CoordinateSystem cs)
167 {
168 if ((ny<0) || (ny>2))
169 return nan("");
170 return GetCoords(cs)[ny];
171 }
172
GetCoordPS(int ny)173 ParameterScalar* ParameterCoord::GetCoordPS(int ny)
174 {
175 if ((ny>=0) && (ny<3))
176 return m_Coords[ny];
177 return 0;
178 }
179
GetNativeCoords() const180 const double* ParameterCoord::GetNativeCoords() const
181 {
182 switch (m_CoordSystem)
183 {
184 default:
185 case CARTESIAN:
186 return GetCartesianCoords();
187 case CYLINDRICAL:
188 return GetCylindricalCoords();
189 }
190 return NULL; //this should not happen...
191 }
192
GetCoords(CoordinateSystem cs) const193 const double* ParameterCoord::GetCoords(CoordinateSystem cs) const
194 {
195 switch (cs)
196 {
197 case CARTESIAN:
198 return GetCartesianCoords();
199 case CYLINDRICAL:
200 return GetCylindricalCoords();
201 default:
202 return GetNativeCoords();
203 }
204 }
205
Evaluate(std::string * ErrStr)206 bool ParameterCoord::Evaluate(std::string *ErrStr)
207 {
208 int EC=0;
209 bool bOK=true;
210 for (int i=0;i<3;++i)
211 {
212 EC=m_Coords[i]->Evaluate();
213 if (EC!=ParameterScalar::PS_NO_ERROR) bOK=false;
214 if ((EC!=ParameterScalar::PS_NO_ERROR) && (ErrStr!=NULL))
215 {
216 std::stringstream stream;
217 stream << std::endl << "Error in ParameterCoord (component: " << i << "): ";
218 ErrStr->append(stream.str());
219 PSErrorCode2Msg(EC,ErrStr);
220 }
221 }
222 return bOK;
223 }
224
Copy(ParameterCoord * pc)225 void ParameterCoord::Copy(ParameterCoord* pc)
226 {
227 m_CoordSystem = pc->m_CoordSystem;
228 for (int n=0;n<3;++n)
229 {
230 delete m_Coords[n];
231 m_Coords[n] = new ParameterScalar(pc->m_Coords[n]);
232 }
233 Update();
234 }
235
Update()236 void ParameterCoord::Update()
237 {
238 double coords[3] = {m_Coords[0]->GetValue(),m_Coords[1]->GetValue(),m_Coords[2]->GetValue()};
239 TransformCoordSystem(coords, m_CartesianCoords, m_CoordSystem, CARTESIAN);
240 TransformCoordSystem(coords, m_CylindricalCoords, m_CoordSystem, CYLINDRICAL);
241 }
242
Write2XML(TiXmlElement * elem,bool parameterised)243 bool ParameterCoord::Write2XML(TiXmlElement *elem, bool parameterised)
244 {
245 if (elem==NULL)
246 return false;
247 WriteTerm(*m_Coords[0],*elem,"X",parameterised);
248 WriteTerm(*m_Coords[1],*elem,"Y",parameterised);
249 WriteTerm(*m_Coords[2],*elem,"Z",parameterised);
250 return true;
251 }
252
ReadFromXML(TiXmlElement * elem)253 bool ParameterCoord::ReadFromXML(TiXmlElement *elem)
254 {
255 if (elem==NULL)
256 return false;
257 if (ReadTerm(*m_Coords[0],*elem,"X")==false) return false;
258 if (ReadTerm(*m_Coords[1],*elem,"Y")==false) return false;
259 if (ReadTerm(*m_Coords[2],*elem,"Z")==false) return false;
260 return true;
261 }
262