diff --git a/Modules/PhotoacousticSimulation/src/Algorithms/mitkPhotoacousticVessel.cpp b/Modules/PhotoacousticSimulation/src/Algorithms/mitkPhotoacousticVessel.cpp index ca4c4efb5c..1c7cc04292 100644 --- a/Modules/PhotoacousticSimulation/src/Algorithms/mitkPhotoacousticVessel.cpp +++ b/Modules/PhotoacousticSimulation/src/Algorithms/mitkPhotoacousticVessel.cpp @@ -1,162 +1,162 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkPhotoacousticVessel.h" #include #include #include mitk::PhotoacousticVessel::PhotoacousticVessel(): m_Range(M_PI/16, M_PI/8), m_Sign(-1, 1) { srand(std::chrono::duration_cast(std::chrono::high_resolution_clock::now().time_since_epoch()).count()); m_Finished = false; m_Position = nullptr; m_Direction = nullptr; m_Radius = -1; m_AbsorptionCoefficient = -1; m_ScatteringCoefficient = -1; m_AnisotropyCoefficient = -1; m_VesselMeanderStrategy = nullptr; m_WalkedDistance = 0; m_State = UNINITIALIZED; } mitk::PhotoacousticVessel::~PhotoacousticVessel() { m_Position = nullptr; m_Direction = nullptr; m_VesselMeanderStrategy = nullptr; m_State = UNINITIALIZED; } void mitk::PhotoacousticVessel::Initialize(mitk::PhotoacousticSmartVector::Pointer initialPosition, mitk::PhotoacousticSmartVector::Pointer initialDirection, double initialRadius, double absorptionCoefficient, double scatteringCoefficient, double anisotophyCoefficient, double bifurcationFrequency, std::mt19937* rng) { m_Radius = initialRadius; m_AbsorptionCoefficient = absorptionCoefficient; m_ScatteringCoefficient = scatteringCoefficient; m_AnisotropyCoefficient = anisotophyCoefficient; m_Finished = false; m_Position = initialPosition; m_Direction = initialDirection; m_VesselMeanderStrategy = mitk::PhotoacousticVesselMeanderStrategy::New(); m_State = INITIALIZED; std::normal_distribution<> factor(1, 0.2); m_BifurcationFrequency = bifurcationFrequency * factor(*rng); } void mitk::PhotoacousticVessel::ExpandVessel(mitk::PhotoacousticVolume::Pointer volume, CalculateNewVesselPositionCallback calculateNewPosition, double bendingFactor, std::mt19937* rng) { AssertState(INITIALIZED); mitk::PhotoacousticSmartVector::Pointer oldPosition = mitk::PhotoacousticSmartVector::New(); oldPosition->SetValue(m_Position); (m_VesselMeanderStrategy->*calculateNewPosition)(m_Position, m_Direction, bendingFactor, rng); DrawVesselInVolume(oldPosition, volume); } bool mitk::PhotoacousticVessel::CanBifurcate() { return m_BifurcationFrequency < m_WalkedDistance; } mitk::PhotoacousticVessel::Pointer mitk::PhotoacousticVessel::Bifurcate(std::mt19937* rng) { AssertState(INITIALIZED); mitk::PhotoacousticVessel::Pointer newVessel = mitk::PhotoacousticVessel::New(); mitk::PhotoacousticSmartVector::Pointer newDirection = m_Direction->Clone(); - double thetaChange = m_Range(*rng) * (m_Sign(*rng) < 1 ? -1 : 1); - double phiChange = m_Range(*rng) * (m_Sign(*rng) < 1 ? -1 : 1); + double thetaChange = m_Range(*rng) * (m_Sign(*rng) < 0 ? -1 : 1); + double phiChange = m_Range(*rng) * (m_Sign(*rng) < 0 ? -1 : 1); MITK_INFO << "Theta change: " << thetaChange; MITK_INFO << "Phi change: " << phiChange; - MITK_INFO << "(m_Sign(*rng) = " << (m_Sign(*rng); + MITK_INFO << "(m_Sign(*rng) = " << (m_Sign(*rng)); newDirection->Rotate(thetaChange, phiChange); m_Direction->Rotate(-thetaChange, -phiChange); std::uniform_real_distribution<> rangeRadius(m_Radius*0.6, m_Radius*0.8); double newRadius = rangeRadius(*rng); m_Radius = sqrt(m_Radius*m_Radius - newRadius*newRadius); newVessel->Initialize(m_Position->Clone(), newDirection, newRadius, m_AbsorptionCoefficient, m_ScatteringCoefficient, m_AnisotropyCoefficient, m_BifurcationFrequency, rng); m_WalkedDistance = 0; return newVessel; } void mitk::PhotoacousticVessel::DrawVesselInVolume(mitk::PhotoacousticSmartVector::Pointer fromPosition, mitk::PhotoacousticVolume::Pointer volume) { AssertState(INITIALIZED); mitk::PhotoacousticSmartVector::Pointer diffVector = mitk::PhotoacousticSmartVector::New(); diffVector->SetElement(0, fromPosition->GetElement(0)-m_Position->GetElement(0)); diffVector->SetElement(1, fromPosition->GetElement(1)-m_Position->GetElement(1)); diffVector->SetElement(2, fromPosition->GetElement(2)-m_Position->GetElement(2)); mitk::PhotoacousticSmartVector::Pointer stepSize = mitk::PhotoacousticSmartVector::New(); stepSize->SetValue(m_Direction); stepSize->Scale(SCALING_FACTOR); while (diffVector->GetNorm() >= SCALING_FACTOR) { m_WalkedDistance += stepSize->GetNorm(); fromPosition->SetElement(0, fromPosition->GetElement(0)+stepSize->GetElement(0)); fromPosition->SetElement(1, fromPosition->GetElement(1)+stepSize->GetElement(1)); fromPosition->SetElement(2, fromPosition->GetElement(2)+stepSize->GetElement(2)); int xPos = fromPosition->GetElement(0); int yPos = fromPosition->GetElement(1); int zPos = fromPosition->GetElement(2); for(int x = xPos - m_Radius; x <= xPos + m_Radius; x++) for(int y = yPos - m_Radius; y <= yPos + m_Radius; y++) for(int z = zPos - m_Radius; z <= zPos + m_Radius; z++) { if( m_Radius*m_Radius >= (x-xPos)*(x-xPos)+(y-yPos)*(y-yPos)+(z-zPos)*(z-zPos)) { volume->SetVolumeValues(x, y, z, m_AbsorptionCoefficient, m_ScatteringCoefficient, m_AnisotropyCoefficient, mitk::PhotoacousticVolume::SegmentationType::VESSEL); } } diffVector->SetElement(0, fromPosition->GetElement(0)-m_Position->GetElement(0)); diffVector->SetElement(1, fromPosition->GetElement(1)-m_Position->GetElement(1)); diffVector->SetElement(2, fromPosition->GetElement(2)-m_Position->GetElement(2)); if(!volume->IsInsideVolume(xPos, yPos, zPos)) { m_Radius = 0; break; } } } bool mitk::PhotoacousticVessel::IsFinished() { return m_Radius < MIN_RADIUS; }