summaryrefslogtreecommitdiffstats
path: root/src/ConeProjectionGeometry3D.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ConeProjectionGeometry3D.cpp')
-rw-r--r--src/ConeProjectionGeometry3D.cpp228
1 files changed, 228 insertions, 0 deletions
diff --git a/src/ConeProjectionGeometry3D.cpp b/src/ConeProjectionGeometry3D.cpp
new file mode 100644
index 0000000..129e675
--- /dev/null
+++ b/src/ConeProjectionGeometry3D.cpp
@@ -0,0 +1,228 @@
+/*
+-----------------------------------------------------------------------
+Copyright 2012 iMinds-Vision Lab, University of Antwerp
+
+Contact: astra@ua.ac.be
+Website: http://astra.ua.ac.be
+
+
+This file is part of the
+All Scale Tomographic Reconstruction Antwerp Toolbox ("ASTRA Toolbox").
+
+The ASTRA Toolbox 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 3 of the License, or
+(at your option) any later version.
+
+The ASTRA Toolbox 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 the ASTRA Toolbox. If not, see <http://www.gnu.org/licenses/>.
+
+-----------------------------------------------------------------------
+$Id$
+*/
+
+#include "astra/ConeProjectionGeometry3D.h"
+
+#include <boost/lexical_cast.hpp>
+#include <cstring>
+
+using namespace std;
+
+namespace astra
+{
+
+//----------------------------------------------------------------------------------------
+// Default constructor.
+CConeProjectionGeometry3D::CConeProjectionGeometry3D() :
+ CProjectionGeometry3D()
+{
+ m_fOriginSourceDistance = 0.0f;
+ m_fOriginDetectorDistance = 0.0f;
+}
+
+//----------------------------------------------------------------------------------------
+// Constructor.
+CConeProjectionGeometry3D::CConeProjectionGeometry3D(int _iProjectionAngleCount,
+ int _iDetectorRowCount,
+ int _iDetectorColCount,
+ float32 _fDetectorWidth,
+ float32 _fDetectorHeight,
+ const float32* _pfProjectionAngles,
+ float32 _fOriginSourceDistance,
+ float32 _fOriginDetectorDistance) :
+ CProjectionGeometry3D()
+{
+ initialize(_iProjectionAngleCount,
+ _iDetectorRowCount,
+ _iDetectorColCount,
+ _fDetectorWidth,
+ _fDetectorHeight,
+ _pfProjectionAngles,
+ _fOriginSourceDistance,
+ _fOriginDetectorDistance);
+}
+
+//----------------------------------------------------------------------------------------
+// Destructor.
+CConeProjectionGeometry3D::~CConeProjectionGeometry3D()
+{
+
+}
+
+//---------------------------------------------------------------------------------------
+// Initialize - Config
+bool CConeProjectionGeometry3D::initialize(const Config& _cfg)
+{
+ ASTRA_ASSERT(_cfg.self);
+ ConfigStackCheck<CProjectionGeometry3D> CC("ConeProjectionGeometry3D", this, _cfg);
+
+ // initialization of parent class
+ CProjectionGeometry3D::initialize(_cfg);
+
+ // Required: DistanceOriginDetector
+ XMLNode* node = _cfg.self->getSingleNode("DistanceOriginDetector");
+ ASTRA_CONFIG_CHECK(node, "ConeProjectionGeometry3D", "No DistanceOriginDetector tag specified.");
+ m_fOriginDetectorDistance = boost::lexical_cast<float32>(node->getContent());
+ ASTRA_DELETE(node);
+ CC.markNodeParsed("DistanceOriginDetector");
+
+ // Required: DetectorOriginSource
+ node = _cfg.self->getSingleNode("DistanceOriginSource");
+ ASTRA_CONFIG_CHECK(node, "ConeProjectionGeometry3D", "No DistanceOriginSource tag specified.");
+ m_fOriginSourceDistance = boost::lexical_cast<float32>(node->getContent());
+ ASTRA_DELETE(node);
+ CC.markNodeParsed("DistanceOriginSource");
+
+ // success
+ m_bInitialized = _check();
+ return m_bInitialized;
+}
+
+//----------------------------------------------------------------------------------------
+// Initialization.
+bool CConeProjectionGeometry3D::initialize(int _iProjectionAngleCount,
+ int _iDetectorRowCount,
+ int _iDetectorColCount,
+ float32 _fDetectorWidth,
+ float32 _fDetectorHeight,
+ const float32* _pfProjectionAngles,
+ float32 _fOriginSourceDistance,
+ float32 _fOriginDetectorDistance)
+{
+ _initialize(_iProjectionAngleCount,
+ _iDetectorRowCount,
+ _iDetectorColCount,
+ _fDetectorWidth,
+ _fDetectorHeight,
+ _pfProjectionAngles);
+
+ m_fOriginSourceDistance = _fOriginSourceDistance;
+ m_fOriginDetectorDistance = _fOriginDetectorDistance;
+
+ // success
+ m_bInitialized = _check();
+ return m_bInitialized;
+}
+
+//----------------------------------------------------------------------------------------
+// Clone
+CProjectionGeometry3D* CConeProjectionGeometry3D::clone() const
+{
+ CConeProjectionGeometry3D* res = new CConeProjectionGeometry3D();
+ res->m_bInitialized = m_bInitialized;
+ res->m_iProjectionAngleCount = m_iProjectionAngleCount;
+ res->m_iDetectorRowCount = m_iDetectorRowCount;
+ res->m_iDetectorColCount = m_iDetectorColCount;
+ res->m_iDetectorTotCount = m_iDetectorTotCount;
+ res->m_fDetectorSpacingX = m_fDetectorSpacingX;
+ res->m_fDetectorSpacingY = m_fDetectorSpacingY;
+ res->m_pfProjectionAngles = new float32[m_iProjectionAngleCount];
+ memcpy(res->m_pfProjectionAngles, m_pfProjectionAngles, sizeof(float32)*m_iProjectionAngleCount);
+ res->m_fOriginSourceDistance = m_fOriginSourceDistance;
+ res->m_fOriginDetectorDistance = m_fOriginDetectorDistance;
+ return res;
+}
+
+//----------------------------------------------------------------------------------------
+// is equal
+bool CConeProjectionGeometry3D::isEqual(const CProjectionGeometry3D* _pGeom2) const
+{
+ if (_pGeom2 == NULL) return false;
+
+ // try to cast argument to CParallelProjectionGeometry3D
+ const CConeProjectionGeometry3D* pGeom2 = dynamic_cast<const CConeProjectionGeometry3D*>(_pGeom2);
+ if (pGeom2 == NULL) return false;
+
+ // both objects must be initialized
+ if (!m_bInitialized || !pGeom2->m_bInitialized) return false;
+
+ // check all values
+ if (m_iProjectionAngleCount != pGeom2->m_iProjectionAngleCount) return false;
+ if (m_iDetectorRowCount != pGeom2->m_iDetectorRowCount) return false;
+ if (m_iDetectorColCount != pGeom2->m_iDetectorColCount) return false;
+ if (m_iDetectorTotCount != pGeom2->m_iDetectorTotCount) return false;
+ if (m_fDetectorSpacingX != pGeom2->m_fDetectorSpacingX) return false;
+ if (m_fDetectorSpacingY != pGeom2->m_fDetectorSpacingY) return false;
+ if (m_fOriginSourceDistance != pGeom2->m_fOriginSourceDistance) return false;
+ if (m_fOriginDetectorDistance != pGeom2->m_fOriginDetectorDistance) return false;
+
+ for (int i = 0; i < m_iProjectionAngleCount; ++i) {
+ if (m_pfProjectionAngles[i] != pGeom2->m_pfProjectionAngles[i]) return false;
+ }
+
+ return true;
+}
+
+//----------------------------------------------------------------------------------------
+// is of type
+bool CConeProjectionGeometry3D::isOfType(const std::string& _sType) const
+{
+ return (_sType == "cone");
+}
+
+//----------------------------------------------------------------------------------------
+void CConeProjectionGeometry3D::toXML(XMLNode* _sNode) const
+{
+ _sNode->addAttribute("type", "cone");
+ _sNode->addChildNode("DetectorSpacingX", m_fDetectorSpacingX);
+ _sNode->addChildNode("DetectorSpacingY", m_fDetectorSpacingY);
+ _sNode->addChildNode("DetectorRowCount", m_iDetectorRowCount);
+ _sNode->addChildNode("DetectorColCount", m_iDetectorColCount);
+ _sNode->addChildNode("ProjectionAngles", m_pfProjectionAngles, m_iProjectionAngleCount);
+ _sNode->addChildNode("DistanceOriginDetector", m_fOriginDetectorDistance);
+ _sNode->addChildNode("DistanceOriginSource", m_fOriginSourceDistance);
+}
+//----------------------------------------------------------------------------------------
+
+CVector3D CConeProjectionGeometry3D::getProjectionDirection(int _iProjectionIndex, int _iDetectorIndex) const
+{
+ float32 fSrcX = -m_fOriginSourceDistance;
+ float32 fSrcY = 0.0f;
+ float32 fSrcZ = 0.0f;
+
+ float32 fDetX = m_fOriginDetectorDistance;
+ float32 fDetY = 0.0f;
+ float32 fDetZ = 0.0f;
+
+ fDetY += indexToDetectorOffsetX(_iDetectorIndex);
+ fDetZ += indexToDetectorOffsetY(_iDetectorIndex);
+
+ float32 angle = m_pfProjectionAngles[_iProjectionIndex];
+
+ #define ROTATE(name,alpha) do { float32 tX = f##name##X * cos(alpha) - f##name##Y * sin(alpha); f##name##Y = f##name##X * sin(alpha) + f##name##Y * cos(alpha); f##name##X = tX; } while(0)
+
+ ROTATE(Src, angle);
+ ROTATE(Det, angle);
+
+ #undef ROTATE
+
+ CVector3D ret(fDetX - fSrcX, fDetY - fSrcY, fDetZ - fDetZ);
+ return ret;
+}
+
+} // end namespace astra