#pragma once #include "stdafx.h" #include "GBFieldData.h" #include "CGBLevel.h" #include namespace OTSGBCalculate { using namespace std; using namespace OTSDATA; #pragma region PrivateCode COTSParticlePtr CGBFieldData::FindAdjacentParticle(COTSParticlePtr p, COTSParticleList plist) { auto adjacentPart = find_if(plist.begin(), plist.end(), [p](COTSParticlePtr pBParticle) { //the conditional particle COTSRect rectParticle = p->GetOTSRect(); CPoint ptParticleCenter = rectParticle.GetCenterPoint(); int Bottom = rectParticle.GetBottomRight().y; int Top = rectParticle.GetTopLeft().y; //the iterational particle COTSRect rectBCurParticle = pBParticle->GetOTSRect(); CPoint ptBParticleCenter = rectBCurParticle.GetCenterPoint(); int BottomB = rectBCurParticle.GetBottomRight().y; int TopB = rectBCurParticle.GetTopLeft().y; if (rectParticle == rectBCurParticle) { return false; } double dd = 0, ds = 0; ds = abs(ptParticleCenter.x - ptBParticleCenter.x); if (ds < 10 )//recognize these two particle in the same level { if (Bottom > TopB)//current particle is on the above { dd = Bottom - TopB; if (dd < 40)//recognize these two particle in the same vertical string. { return true; } } else if (BottomB > Top) //current particle is on the below { dd = BottomB - Top; if (dd < 40) { return true; } } } return false; }); if (adjacentPart == plist.end()) { return nullptr; } else { return *adjacentPart; } } #pragma endregion CGBFieldData::CGBFieldData() // constructor { Init(); } CGBFieldData::CGBFieldData(const CGBFieldData& a_oSource) // copy constructor { // can't copy itself if (&a_oSource == this) { return; } // copy data over Duplicate(a_oSource); } CGBFieldData::CGBFieldData(CGBFieldData* a_poSource) // copy constructor { // input check ASSERT(a_poSource); if (!a_poSource) { return; } // can't copy itself if (a_poSource == this) { return; } // copy data over Duplicate(*a_poSource); } CGBFieldData& CGBFieldData::operator=(const CGBFieldData& a_oSource) // =operator { // cleanup Cleanup(); // copy the class data over Duplicate(a_oSource); // return class return *this; } BOOL CGBFieldData::operator==(const CGBFieldData& a_oSource) // =operator { // return test result return((m_nFrameId == a_oSource.m_nFrameId) && (*m_pALevel.get() == *a_oSource.m_pALevel.get()) && (*m_pBLevel.get() == *a_oSource.m_pBLevel.get()) && (*m_pCLevel.get() == *a_oSource.m_pCLevel.get()) && (*m_pDLevel.get() == *a_oSource.m_pDLevel.get()) && (*m_pDSLevel.get() == *a_oSource.m_pDSLevel.get())); } CGBFieldData::~CGBFieldData() // detractor { Cleanup(); } // serialization void CGBFieldData::Serialize(bool isStoring, tinyxml2::XMLDocument *classDoc, tinyxml2::XMLElement *rootNode) { xmls::xInt xFrameId; xmls::Slo slo; slo.Register("FrameId", &xFrameId); slo.Register("ALevel", m_pALevel.get()); slo.Register("BLevel", m_pBLevel.get()); slo.Register("CLevel", m_pCLevel.get()); slo.Register("DLevel", m_pDLevel.get()); slo.Register("DSLevel", m_pDSLevel.get()); if (isStoring) { xFrameId = m_nFrameId; slo.Serialize(true, classDoc, rootNode); } else { slo.Serialize(false, classDoc, rootNode); m_nFrameId = xFrameId.value(); } } // cleanup void CGBFieldData::Cleanup() { } // initialization void CGBFieldData::Init() { // id m_nFrameId = -1; // A level m_pALevel = CGBLevelPtr(new CGBLevel(this, GB_LEVEL_TYPE::A_TYPE)); // B level m_pBLevel = CGBLevelPtr(new CGBLevel(this, GB_LEVEL_TYPE::B_TYPE)); // C level m_pCLevel = CGBLevelPtr(new CGBLevel(this, GB_LEVEL_TYPE::C_TYPE)); // D level m_pDLevel = CGBLevelPtr(new CGBLevel(this, GB_LEVEL_TYPE::D_TYPE)); // DS level m_pDSLevel = CGBLevelPtr(new CGBLevel(this, GB_LEVEL_TYPE::DS_TYPE)); // DSulfide level m_pDSulfidLevel = CGBLevelPtr(new CGBLevel(this, GB_LEVEL_TYPE::DSulfide_TYPE)); listAThinParticles.clear(); listAWideParticles.clear(); listASuperParticles.clear(); listBThinParticles.clear(); listBWideParticles.clear(); listBSuperParticles.clear(); listCThinParticles.clear(); listCWideParticles.clear(); listCSuperParticles.clear(); listDThinParticles.clear(); listDWideParticles.clear(); listDSuperParticles.clear(); listDSParticles.clear(); listDSulfideThinParticles.clear(); listDSulfideWideParticles.clear(); listDSulfideSuperParticles.clear(); } // duplication void CGBFieldData::Duplicate(const CGBFieldData& a_oSource) { // initialization Init(); // id int m_nFrameId; // A level m_pALevel = CGBLevelPtr(new CGBLevel(*a_oSource.m_pALevel.get())); // B level m_pBLevel = CGBLevelPtr(new CGBLevel(*a_oSource.m_pBLevel.get())); // C level m_pCLevel = CGBLevelPtr(new CGBLevel(*a_oSource.m_pCLevel.get())); // D level m_pDLevel = CGBLevelPtr(new CGBLevel(*a_oSource.m_pDLevel.get())); // DS level m_pDSLevel = CGBLevelPtr(new CGBLevel(*a_oSource.m_pDSLevel.get())); m_nFrameId = a_oSource.m_nFrameId; } // caculate Level by method 1 void CGBFieldData::CaculateLevelByMethod1() { // according to the shape if (m_listParticles.empty()) { return; } vector listBAndDParticles;// listBAndDParticles.clear(); // get all the all particles for each level mapAllParticles.clear(); for (auto pParticle : m_listParticles) { // compute length width ratio CRect rectParticle = pParticle->GetParticleRect(); //check the denominator is zero or not if (rectParticle.Width() == 0) { continue; } //获取最大长度和最小宽度 double h = pParticle->GetDMax(); double w = pParticle->GetDMin(); double dLengthWidthRatio = h / w; if (dLengthWidthRatio < 1) { dLengthWidthRatio = 1 / dLengthWidthRatio; } if (dLengthWidthRatio >= 3)//长宽比大于3的颗粒,根据化学元素不同,分为A类和C类 { //A or C class GB_CHEMICAL_TYPE nChemicalType = pParticle->GetChemicalType(); if (nChemicalType == GB_CHEMICAL_TYPE::CHE_S) { // A //计算颗粒宽度是属于细系粗系还是超尺寸 GB_WIDTH_TYPE wt = this->CaculateLevelWidth(pParticle, GB_LEVEL_TYPE::A_TYPE); switch (wt) { case GB_WIDTH_TYPE::THIN: listAThinParticles.push_back(pParticle); break; case GB_WIDTH_TYPE::WIDE: listAWideParticles.push_back(pParticle); break; case GB_WIDTH_TYPE::SUPER: listASuperParticles.push_back(pParticle); break; } mapAllParticles[pParticle] = GBParticle(pParticle, GB_LEVEL_TYPE::A_TYPE, wt); } else if (nChemicalType == GB_CHEMICAL_TYPE::CHE_O || nChemicalType== GB_CHEMICAL_TYPE::CHE_Si || nChemicalType == GB_CHEMICAL_TYPE::CHE_Al) { // C //计算颗粒宽度是属于细系粗系还是超尺寸 GB_WIDTH_TYPE wt = this->CaculateLevelWidth(pParticle, GB_LEVEL_TYPE::C_TYPE); switch (wt) { case GB_WIDTH_TYPE::THIN: listCThinParticles.push_back(pParticle); break; case GB_WIDTH_TYPE::WIDE: listCWideParticles.push_back(pParticle); break; case GB_WIDTH_TYPE::SUPER: listCSuperParticles.push_back(pParticle); break; } mapAllParticles[pParticle] = GBParticle(pParticle, GB_LEVEL_TYPE::C_TYPE, wt); } } else//长宽比小于3的颗粒,有3种情况,一种是串条状的B类颗粒,一种是单独的D类颗粒,如果费雷特直径大于13则为DS类颗粒 { // B, or D or DS // compute Feret's diameter double dFeretDiameter = pParticle->GetFeretDiameter(); if (dFeretDiameter >= 13) { // DS listDSParticles.push_back(pParticle); } else { if (pParticle->GetChemicalType() == GB_CHEMICAL_TYPE::CHE_S)//if it contains sulfide then it is a A particle. { GB_LEVEL_TYPE partType = GB_LEVEL_TYPE::A_TYPE;//把类型设为有效类型,以便不再找这个颗粒 //计算颗粒宽度是属于细系粗系还是超尺寸 GB_WIDTH_TYPE wt = this->CaculateLevelWidth(pParticle, GB_LEVEL_TYPE::A_TYPE); switch (wt) { case GB_WIDTH_TYPE::THIN: listAThinParticles.push_back(pParticle); break; case GB_WIDTH_TYPE::WIDE: listAWideParticles.push_back(pParticle); break; case GB_WIDTH_TYPE::SUPER: listASuperParticles.push_back(pParticle); break; } mapAllParticles[pParticle] = GBParticle(pParticle, partType, wt); } else { // B or D if (pParticle->GetChemicalType() != GB_CHEMICAL_TYPE::INVALID)//here we take all the particles { GBParticle gbP = GBParticle(pParticle, GB_LEVEL_TYPE::INVALID, GB_WIDTH_TYPE::INVALID); //不能确定是B或D,先设为INVALID listBAndDParticles.push_back(gbP); } } } } } for (auto pGBParticle : listBAndDParticles) { //check if the particle is alone auto adjacentPart = find_if(listBAndDParticles.begin(), listBAndDParticles.end(), [pGBParticle](GBParticle pBParticle) { //the conditional particle COTSRect rectParticle = pGBParticle.myPart->GetOTSRect(); CPoint ptParticleCenter = rectParticle.GetCenterPoint(); int Bottom = rectParticle.GetBottomRight().y; int Top = rectParticle.GetTopLeft().y; //the current iteration particle COTSRect rectBCurParticle = pBParticle.myPart->GetOTSRect(); CPoint ptBParticleCenter = rectBCurParticle.GetCenterPoint(); int BottomB = rectBCurParticle.GetBottomRight().y; int TopB = rectBCurParticle.GetTopLeft().y; if (rectParticle == rectBCurParticle) { return false; } double dd = 0, ds = 0; ds = abs(ptParticleCenter.x - ptBParticleCenter.x); if (ds < 10 )//认为两个颗粒在一条竖直线上,但不在一起 { if (Bottom > TopB)//current particle is on the above { dd = Bottom - TopB; if (dd < 40)//认为这两个颗粒在一个串条上 { return true; } } else if (BottomB > Top) //current particle is on the below { dd = BottomB - Top; if (dd < 40) { return true; } } } return false; }); if (adjacentPart == listBAndDParticles.end())//没找到 { if (pGBParticle.myPart->GetChemicalType() == GB_CHEMICAL_TYPE::CHE_O) { pGBParticle.myType = GB_LEVEL_TYPE::D_TYPE; //计算颗粒宽度是属于细系粗系还是超尺寸 GB_WIDTH_TYPE wt = this->CaculateLevelWidth(pGBParticle.myPart, GB_LEVEL_TYPE::D_TYPE); switch (wt) { case GB_WIDTH_TYPE::THIN: listDThinParticles.push_back(pGBParticle.myPart); break; case GB_WIDTH_TYPE::WIDE: listDWideParticles.push_back(pGBParticle.myPart); break; case GB_WIDTH_TYPE::SUPER: listDSuperParticles.push_back(pGBParticle.myPart); break; } mapAllParticles[pGBParticle.myPart] = GBParticle(pGBParticle.myPart, GB_LEVEL_TYPE::D_TYPE, wt); } } else//找到了相邻接的颗粒,不是孤立的则为B类 { pGBParticle.myType = GB_LEVEL_TYPE::B_TYPE;//把类型设为有效类型,以便不再找这个颗粒 adjacentPart->myType = GB_LEVEL_TYPE::B_TYPE; //计算颗粒宽度是属于细系粗系还是超尺寸 GB_WIDTH_TYPE wt = this->CaculateLevelWidth(pGBParticle.myPart, GB_LEVEL_TYPE::B_TYPE); switch (wt) { case GB_WIDTH_TYPE::THIN: listBThinParticles.insert(pGBParticle.myPart); break; case GB_WIDTH_TYPE::WIDE: listBWideParticles.insert(pGBParticle.myPart); break; case GB_WIDTH_TYPE::SUPER: listBSuperParticles.insert(pGBParticle.myPart); break; } mapAllParticles[pGBParticle.myPart] = GBParticle(pGBParticle.myPart, GB_LEVEL_TYPE::B_TYPE, wt); wt = this->CaculateLevelWidth(adjacentPart->myPart, GB_LEVEL_TYPE::B_TYPE); switch (wt) { case GB_WIDTH_TYPE::THIN: listBThinParticles.insert(adjacentPart->myPart); break; case GB_WIDTH_TYPE::WIDE: listBWideParticles.insert(adjacentPart->myPart); break; case GB_WIDTH_TYPE::SUPER: listBSuperParticles.insert(adjacentPart->myPart); break; } mapAllParticles[adjacentPart->myPart] = GBParticle(adjacentPart->myPart, GB_LEVEL_TYPE::B_TYPE, wt); } } } // caculate Level by method 2 void CGBFieldData::CaculateLevelByMethod2() { vector listABCParticles;// listABCParticles.clear(); if (m_listParticles.empty()) { return; } // get all the all particles for each level for (auto pParticle : m_listParticles) { //IdentifyPartChemicalType(pParticle); //check the denominator is zero or not CRect rectParticle = pParticle->GetParticleRect(); if (rectParticle.Width() == 0) { continue; } //获取最小外接矩形的宽和高 double h = pParticle->GetDMax(); double w = pParticle->GetDMin(); double dLengthWidthRatio = h / w; if (dLengthWidthRatio < 1) { dLengthWidthRatio = 1 / dLengthWidthRatio; } if (dLengthWidthRatio < 3)//长宽比小于3的颗粒,且为孤立的颗粒,根据是否含硫化物,分为D类和DSulfide类,如果费雷特直径大于13 归为DS类 { double dFeretDiameter = pParticle->GetFeretDiameter(); if (dFeretDiameter >= 13) { // DS listDSParticles.push_back(pParticle); } else { // D or Dsulfide auto p = FindAdjacentParticle(pParticle, m_listParticles); if (p == nullptr)//pParticle是一个孤立的颗粒 { GB_CHEMICAL_TYPE ChemicalType = pParticle->GetChemicalType(); if (ChemicalType == GB_CHEMICAL_TYPE::CHE_S) { auto wt = this->CaculateLevelWidth(pParticle, GB_LEVEL_TYPE::DSulfide_TYPE); switch (wt) { case GB_WIDTH_TYPE::THIN: listDSulfideThinParticles.push_back(pParticle); break; case GB_WIDTH_TYPE::WIDE: listDSulfideWideParticles.push_back(pParticle); break; case GB_WIDTH_TYPE::SUPER: listDSulfideSuperParticles.push_back(pParticle); break; } mapAllParticles[pParticle] = GBParticle(pParticle, GB_LEVEL_TYPE::DSulfide_TYPE, wt); } else { auto wt = this->CaculateLevelWidth(pParticle, GB_LEVEL_TYPE::D_TYPE); switch (wt) { case GB_WIDTH_TYPE::THIN: listDThinParticles.push_back(pParticle); break; case GB_WIDTH_TYPE::WIDE: listDWideParticles.push_back(pParticle); break; case GB_WIDTH_TYPE::SUPER: listDSuperParticles.push_back(pParticle); break; } mapAllParticles[pParticle] = GBParticle(pParticle, GB_LEVEL_TYPE::D_TYPE, wt); } } else { listABCParticles.push_back(pParticle); } } } else { listABCParticles.push_back(pParticle); } } for (auto pParticle : listABCParticles) { GB_CHEMICAL_TYPE nChemicalType = pParticle->GetChemicalType(); if (nChemicalType == GB_CHEMICAL_TYPE::CHE_S) { // A //COTSParticlePtr pParticleNew = COTSParticlePtr(pParticle); GB_WIDTH_TYPE wt = this->CaculateLevelWidth(pParticle, GB_LEVEL_TYPE::A_TYPE); switch (wt) { case GB_WIDTH_TYPE::THIN: listAThinParticles.push_back(pParticle); break; case GB_WIDTH_TYPE::WIDE: listAWideParticles.push_back(pParticle); break; case GB_WIDTH_TYPE::SUPER: listASuperParticles.push_back(pParticle); break; } mapAllParticles[pParticle] = GBParticle(pParticle, GB_LEVEL_TYPE::A_TYPE, wt); } else if (nChemicalType == GB_CHEMICAL_TYPE::CHE_Al) { // B GB_WIDTH_TYPE wt = this->CaculateLevelWidth(pParticle, GB_LEVEL_TYPE::B_TYPE); switch (wt) { case GB_WIDTH_TYPE::THIN: listBThinParticles.insert(pParticle); break; case GB_WIDTH_TYPE::WIDE: listBWideParticles.insert(pParticle); break; case GB_WIDTH_TYPE::SUPER: listBSuperParticles.insert(pParticle); break; } mapAllParticles[pParticle] = GBParticle(pParticle, GB_LEVEL_TYPE::B_TYPE, wt); } else if (nChemicalType == GB_CHEMICAL_TYPE::CHE_Si) { // C GB_WIDTH_TYPE wt = this->CaculateLevelWidth(pParticle, GB_LEVEL_TYPE::C_TYPE); switch (wt) { case GB_WIDTH_TYPE::THIN: listCThinParticles.push_back(pParticle); break; case GB_WIDTH_TYPE::WIDE: listCWideParticles.push_back(pParticle); break; case GB_WIDTH_TYPE::SUPER: listCSuperParticles.push_back(pParticle); break; } mapAllParticles[pParticle] = GBParticle(pParticle, GB_LEVEL_TYPE::C_TYPE, wt); } } } // caculate Level by ASTM void CGBFieldData::CaculateLevelASTM() { // according to the shape if (m_listParticles.empty()) { return; } vector listBAndDParticles;// listBAndDParticles.clear(); // get all the all particles for each level mapAllParticles.clear(); for (auto pParticle : m_listParticles) { // compute length width ratio CRect rectParticle = pParticle->GetParticleRect(); //check the denominator is zero or not if (rectParticle.Width() == 0) { continue; } //获取最大长度和最小宽度 double h = pParticle->GetDMax(); double w = pParticle->GetDMin(); double dLengthWidthRatio = h / w; if (dLengthWidthRatio < 1) { dLengthWidthRatio = 1 / dLengthWidthRatio; } if (dLengthWidthRatio >= 3)//长宽比大于3的颗粒,根据化学元素不同,分为A类和C类 { //A or C class GB_CHEMICAL_TYPE nChemicalType = pParticle->GetChemicalType(); if (nChemicalType == GB_CHEMICAL_TYPE::CHE_S) { // A //计算颗粒宽度是属于细系粗系还是超尺寸 GB_WIDTH_TYPE wt = this->CaculateLevelWidth(pParticle, GB_LEVEL_TYPE::A_TYPE); switch (wt) { case GB_WIDTH_TYPE::THIN: listAThinParticles.push_back(pParticle); break; case GB_WIDTH_TYPE::WIDE: listAWideParticles.push_back(pParticle); break; case GB_WIDTH_TYPE::SUPER: listASuperParticles.push_back(pParticle); break; } mapAllParticles[pParticle] = GBParticle(pParticle, GB_LEVEL_TYPE::A_TYPE, wt); } else if (nChemicalType == GB_CHEMICAL_TYPE::CHE_O || nChemicalType == GB_CHEMICAL_TYPE::CHE_Si || nChemicalType == GB_CHEMICAL_TYPE::CHE_Al) { // C //计算颗粒宽度是属于细系粗系还是超尺寸 GB_WIDTH_TYPE wt = this->CaculateLevelWidth(pParticle, GB_LEVEL_TYPE::C_TYPE); switch (wt) { case GB_WIDTH_TYPE::THIN: listCThinParticles.push_back(pParticle); break; case GB_WIDTH_TYPE::WIDE: listCWideParticles.push_back(pParticle); break; case GB_WIDTH_TYPE::SUPER: listCSuperParticles.push_back(pParticle); break; } mapAllParticles[pParticle] = GBParticle(pParticle, GB_LEVEL_TYPE::C_TYPE, wt); } } else//长宽比小于3的颗粒,有3种情况,一种是串条状的B类颗粒,一种是单独的D类颗粒,如果费雷特直径大于13则为DS类颗粒 { // B, or D or DS // compute Feret's diameter double dFeretDiameter = pParticle->GetFeretDiameter(); if (dFeretDiameter >= 13) { // DS listDSParticles.push_back(pParticle); } else { // B or D if (pParticle->GetChemicalType() != GB_CHEMICAL_TYPE::INVALID)//here we take all the particles { GBParticle gbP = GBParticle(pParticle, GB_LEVEL_TYPE::INVALID, GB_WIDTH_TYPE::INVALID); //不能确定是B或D,先设为INVALID listBAndDParticles.push_back(gbP); } } } } for (auto pGBParticle : listBAndDParticles) { // check if the particle is alone auto adjacentPart = find_if(listBAndDParticles.begin(), listBAndDParticles.end(), [pGBParticle](GBParticle pBParticle) { COTSRect rectParticle = pGBParticle.myPart->GetOTSRect(); CPoint ptParticleCenter = rectParticle.GetCenterPoint(); int Bottom = rectParticle.GetBottomRight().y; int Top = rectParticle.GetTopLeft().y; COTSRect rectBCurParticle = pBParticle.myPart->GetOTSRect(); CPoint ptBParticleCenter = rectBCurParticle.GetCenterPoint(); int BottomB = rectBCurParticle.GetBottomRight().y; int TopB = rectBCurParticle.GetTopLeft().y; double dd = 0, ds = 0; ds = abs(ptParticleCenter.x - ptBParticleCenter.x); if (ds <= 15)//认为两个颗粒在一条竖直线上,但不在一起 { if (Bottom > TopB)//current particle is on the above { dd = Bottom - TopB; if (dd < 40)//认为这两个颗粒在一个串条上 { return true; } } else if (BottomB > Top) //current particle is on the below { dd = BottomB - Top; if (dd < 40) { return true; } } } return false; }); if (adjacentPart == listBAndDParticles.end())//没找到 { pGBParticle.myType = GB_LEVEL_TYPE::D_TYPE; //计算颗粒宽度是属于细系粗系还是超尺寸 GB_WIDTH_TYPE wt = this->CaculateLevelWidth(pGBParticle.myPart, GB_LEVEL_TYPE::D_TYPE); switch (wt) { case GB_WIDTH_TYPE::THIN: listDThinParticles.push_back(pGBParticle.myPart); break; case GB_WIDTH_TYPE::WIDE: listDWideParticles.push_back(pGBParticle.myPart); break; case GB_WIDTH_TYPE::SUPER: listDSuperParticles.push_back(pGBParticle.myPart); break; } mapAllParticles[pGBParticle.myPart] = GBParticle(pGBParticle.myPart, GB_LEVEL_TYPE::D_TYPE, wt); } else//找到了相邻接的颗粒,不是孤立的则为B类 { pGBParticle.myType = GB_LEVEL_TYPE::B_TYPE;//把类型设为有效类型,以便不再找这个颗粒 adjacentPart->myType = GB_LEVEL_TYPE::B_TYPE; //计算颗粒宽度是属于细系粗系还是超尺寸 GB_WIDTH_TYPE wt = this->CaculateLevelWidth(pGBParticle.myPart, GB_LEVEL_TYPE::B_TYPE); switch (wt) { case GB_WIDTH_TYPE::THIN: listBThinParticles.insert(pGBParticle.myPart); break; case GB_WIDTH_TYPE::WIDE: listBWideParticles.insert(pGBParticle.myPart); break; case GB_WIDTH_TYPE::SUPER: listBSuperParticles.insert(pGBParticle.myPart); break; } mapAllParticles[pGBParticle.myPart] = GBParticle(pGBParticle.myPart, GB_LEVEL_TYPE::B_TYPE, wt); wt = this->CaculateLevelWidth(adjacentPart->myPart, GB_LEVEL_TYPE::B_TYPE); switch (wt) { case GB_WIDTH_TYPE::THIN: listBThinParticles.insert(adjacentPart->myPart); break; case GB_WIDTH_TYPE::WIDE: listBWideParticles.insert(adjacentPart->myPart); break; case GB_WIDTH_TYPE::SUPER: listBSuperParticles.insert(adjacentPart->myPart); break; } mapAllParticles[adjacentPart->myPart] = GBParticle(adjacentPart->myPart, GB_LEVEL_TYPE::B_TYPE, wt); } } } // caculate Level by DIN void CGBFieldData::CaculateLevelDIN(COTSParticleList listParticle) { // according to the shape if (listParticle.empty()) { return; } vector listBAndDParticles;// listBAndDParticles.clear(); // get all the all particles for each level mapAllParticles.clear(); for (auto pParticle : listParticle) { // compute length width ratio CRect rectParticle = pParticle->GetParticleRect(); //check the denominator is zero or not if (rectParticle.Width() == 0) { continue; } //获取最大长度和最小宽度 double h = pParticle->GetDMax(); double w = pParticle->GetDMin(); double dLengthWidthRatio = h / w; if (dLengthWidthRatio < 1) { dLengthWidthRatio = 1 / dLengthWidthRatio; } if (dLengthWidthRatio >= 3)//长宽比大于3的颗粒,根据化学元素不同,分为A类和C类 { //A or C class GB_CHEMICAL_TYPE nChemicalType = pParticle->GetChemicalType(); if (nChemicalType == GB_CHEMICAL_TYPE::CHE_S) { // A //计算颗粒宽度是属于细系粗系还是超尺寸 GB_WIDTH_TYPE wt = this->CaculateLevelWidth(pParticle, GB_LEVEL_TYPE::A_TYPE); if (wt == GB_WIDTH_TYPE::THIN || wt == GB_WIDTH_TYPE::WIDE || wt == GB_WIDTH_TYPE::SUPER) { listAThinParticles.push_back(pParticle); } mapAllParticles[pParticle] = GBParticle(pParticle, GB_LEVEL_TYPE::A_TYPE, wt); } else if (nChemicalType == GB_CHEMICAL_TYPE::CHE_O) { // C //计算颗粒宽度是属于细系粗系还是超尺寸 GB_WIDTH_TYPE wt = this->CaculateLevelWidth(pParticle, GB_LEVEL_TYPE::C_TYPE); if (wt == GB_WIDTH_TYPE::THIN || wt == GB_WIDTH_TYPE::WIDE || wt == GB_WIDTH_TYPE::SUPER) { listAThinParticles.push_back(pParticle); } mapAllParticles[pParticle] = GBParticle(pParticle, GB_LEVEL_TYPE::C_TYPE, wt); } } else//长宽比小于3的颗粒,有3种情况,一种是串条状的B类颗粒,一种是单独的D类颗粒,如果费雷特直径大于13则为DS类颗粒 { // B, or D or DS // compute Feret's diameter double dFeretDiameter = pParticle->GetFeretDiameter(); if (dFeretDiameter >= 13) { // DS listDSParticles.push_back(pParticle); } else { // B or D GBParticle gbP = GBParticle(pParticle, GB_LEVEL_TYPE::INVALID, GB_WIDTH_TYPE::INVALID); //不能确定是B或D,先设为INVALID listBAndDParticles.push_back(gbP); } } } { for (auto pGBParticle : listBAndDParticles) { // check if the particle is alone auto adjacentPart = find_if(listBAndDParticles.begin(), listBAndDParticles.end(), [pGBParticle](GBParticle pBParticle) { CRect rectParticle = pGBParticle.myPart->GetParticleRect(); CPoint ptParticleCenter = rectParticle.CenterPoint(); int Bottom = rectParticle.BottomRight().y; int Top = rectParticle.TopLeft().y; CRect rectBCurParticle = pBParticle.myPart->GetParticleRect(); CPoint ptBParticleCenter = rectBCurParticle.CenterPoint(); int BottomB = rectBCurParticle.BottomRight().y; int TopB = rectBCurParticle.TopLeft().y; double dd = 0, ds = 0; ds = abs(ptParticleCenter.x - ptBParticleCenter.x); if (ds <= 15)//认为两个颗粒在一条竖直线上,但不在一起 { if (Bottom > TopB)//current particle is on the above { dd = Bottom - TopB; if (dd < 40)//认为这两个颗粒在一个串条上 { return true; } } else if (BottomB > Top) //current particle is on the below { dd = BottomB - Top; if (dd < 40) { return true; } } } return false; }); if (adjacentPart == listBAndDParticles.end())//没找到 { pGBParticle.myType = GB_LEVEL_TYPE::D_TYPE; //计算颗粒宽度是属于细系粗系还是超尺寸 GB_WIDTH_TYPE wt = this->CaculateLevelWidth(pGBParticle.myPart, GB_LEVEL_TYPE::D_TYPE); if (wt == GB_WIDTH_TYPE::THIN || wt == GB_WIDTH_TYPE::WIDE || wt == GB_WIDTH_TYPE::SUPER) { listDThinParticles.push_back(pGBParticle.myPart); } mapAllParticles[pGBParticle.myPart] = GBParticle(pGBParticle.myPart, GB_LEVEL_TYPE::D_TYPE, wt); } else//找到了相邻接的颗粒,不是孤立的则为B类 { pGBParticle.myType = GB_LEVEL_TYPE::B_TYPE;//把类型设为有效类型,以便不再找这个颗粒 adjacentPart->myType = GB_LEVEL_TYPE::B_TYPE; //计算颗粒宽度是属于细系粗系还是超尺寸 GB_WIDTH_TYPE wt = this->CaculateLevelWidth(pGBParticle.myPart, GB_LEVEL_TYPE::B_TYPE); if (wt == GB_WIDTH_TYPE::THIN || wt == GB_WIDTH_TYPE::WIDE || wt == GB_WIDTH_TYPE::SUPER) { listBThinParticles.insert(pGBParticle.myPart); } mapAllParticles[pGBParticle.myPart] = GBParticle(pGBParticle.myPart, GB_LEVEL_TYPE::B_TYPE, wt); wt = this->CaculateLevelWidth(adjacentPart->myPart, GB_LEVEL_TYPE::B_TYPE); if (wt == GB_WIDTH_TYPE::THIN || wt == GB_WIDTH_TYPE::WIDE || wt == GB_WIDTH_TYPE::SUPER) { listBThinParticles.insert(adjacentPart->myPart); } mapAllParticles[adjacentPart->myPart] = GBParticle(adjacentPart->myPart, GB_LEVEL_TYPE::B_TYPE, wt); } } } } // caculate Level Width BOOL CGBFieldData::CaculateLevelThinWidth(COTSParticleList& a_listParticles, GB_LEVEL_TYPE a_nLevel) { if (a_listParticles.empty()) { return FALSE; } double dMin = 2, dMax = 0; switch ((int)a_nLevel) { case (int)GB_LEVEL_TYPE::A_TYPE: dMax = 4; break; case (int)GB_LEVEL_TYPE::B_TYPE: dMax = 9; break; case (int)GB_LEVEL_TYPE::C_TYPE: dMax = 5; break; case (int)GB_LEVEL_TYPE::D_TYPE: dMax = 8; break; } BOOL bThin = TRUE; for (auto pParticle : a_listParticles) { CRect rectParticle = pParticle->GetParticleRect(); double dWidth = (double)rectParticle.Width(); if (dWidth < dMin || dWidth > dMax) { bThin = FALSE; break; } } return bThin; } GB_WIDTH_TYPE CGBFieldData::CaculateLevelWidth(COTSParticlePtr Particle, GB_LEVEL_TYPE a_nLevel) { double dWidth = (double)Particle->GetDMin(); double dMin = 2, dMax = 0; switch ((int)a_nLevel) { case (int)GB_LEVEL_TYPE::A_TYPE: dMax = 4; break; case (int)GB_LEVEL_TYPE::B_TYPE: dMax = 9; break; case (int)GB_LEVEL_TYPE::C_TYPE: dMax = 5; break; case (int)GB_LEVEL_TYPE::D_TYPE: dMax = 8; break; } if (dWidth < dMin) { return GB_WIDTH_TYPE::INVALID;//小于2um不考虑 } else if (dWidth >= dMin && dWidth < dMax) { return GB_WIDTH_TYPE::THIN; } switch ((int)a_nLevel) { case (int)GB_LEVEL_TYPE::A_TYPE: dMin = 4; dMax = 12; break; case (int)GB_LEVEL_TYPE::B_TYPE: dMin = 9; dMax = 15; break; case (int)GB_LEVEL_TYPE::C_TYPE: dMin = 5; dMax = 12; break; case (int)GB_LEVEL_TYPE::D_TYPE: dMin = 8; dMax = 13; break; } if (dWidth >= dMin && dWidth < dMax) { return GB_WIDTH_TYPE::WIDE; } switch ((int)a_nLevel) { case (int)GB_LEVEL_TYPE::A_TYPE: dMin = 12; break; case (int)GB_LEVEL_TYPE::B_TYPE: dMin = 15; break; case (int)GB_LEVEL_TYPE::C_TYPE: dMin = 12; break; case (int)GB_LEVEL_TYPE::D_TYPE: dMin = 13; break; } if (dWidth >= dMin) { return GB_WIDTH_TYPE::SUPER; } return GB_WIDTH_TYPE::INVALID; } BOOL CGBFieldData::CaculateLevelFatWidth(COTSParticleList& a_listParticles, GB_LEVEL_TYPE a_nLevel) { if (a_listParticles.empty()) { return FALSE; } double dMin = 0, dMax = 0; switch ((int)a_nLevel) { case (int)GB_LEVEL_TYPE::A_TYPE: dMin = 4; dMax = 12; break; case (int)GB_LEVEL_TYPE::B_TYPE: dMin = 9; dMax = 15; break; case (int)GB_LEVEL_TYPE::C_TYPE: dMin = 5; dMax = 12; break; case (int)GB_LEVEL_TYPE::D_TYPE: dMin = 8; dMax = 13; break; } BOOL bFat = TRUE; for (auto pParticle : a_listParticles) { CRect rectParticle = pParticle->GetParticleRect(); double dWidth = (double)rectParticle.Width(); if (dWidth < dMin || dWidth > dMax) { bFat = FALSE; break; } } return bFat; } BOOL CGBFieldData::CaculateSuper(COTSParticleList& a_listParticles, GB_LEVEL_TYPE a_nLevel) { if (a_listParticles.empty()) { return FALSE; } double dMin = 0; switch ((int)a_nLevel) { case (int)GB_LEVEL_TYPE::A_TYPE: dMin = 12; break; case (int)GB_LEVEL_TYPE::B_TYPE: dMin = 15; break; case (int)GB_LEVEL_TYPE::C_TYPE: dMin = 12; break; case (int)GB_LEVEL_TYPE::D_TYPE: dMin = 13; break; } BOOL bSuper = TRUE; for (auto pParticle : a_listParticles) { CRect rectParticle = pParticle->GetParticleRect(); double dWidth = (double)rectParticle.Width(); if (dWidth < dMin) { bSuper = FALSE; break; } } return bSuper; } BOOL CGBFieldData::IdentifyPartChemicalType(COTSParticlePtr Particle) { if (Particle->GetXrayInfo() == NULL) { Particle->SetChemicalType(GB_CHEMICAL_TYPE::INVALID); return false; } auto chamicalList = Particle->GetXrayInfo()->GetElementQuantifyData(); double dOWeight = 0; double dSWeight = 0; double dNWeight = 0; double dSiWeight = 0; double dAlWeight = 0; double dMnWeight = 0; double dFeWeight = 0; double dCWeight = 0; for (auto pElChem : chamicalList) { if (pElChem->GetName().CompareNoCase(STR_O) == 0) { dOWeight = pElChem->GetPercentage(); } else if (pElChem->GetName().CompareNoCase(STR_SUL) == 0) { dSWeight = pElChem->GetPercentage(); } else if (pElChem->GetName().CompareNoCase(STR_N) == 0) { dNWeight = pElChem->GetPercentage(); } else if (pElChem->GetName().CompareNoCase(STR_SI) == 0) { dSiWeight = pElChem->GetPercentage(); } else if (pElChem->GetName().CompareNoCase(STR_Al) == 0) { dAlWeight = pElChem->GetPercentage(); } else if (pElChem->GetName().CompareNoCase(STR_Mn) == 0) { dMnWeight = pElChem->GetPercentage(); } else if (pElChem->GetName().CompareNoCase(STR_Fe) == 0) { dFeWeight = pElChem->GetPercentage(); } else if (pElChem->GetName().CompareNoCase(STR_C) == 0) { dCWeight = pElChem->GetPercentage(); } } if (dSWeight >= MIN_ELEMENT_SUM && dMnWeight > MIN_ELEMENT_SUM) { Particle->SetChemicalType(GB_CHEMICAL_TYPE::CHE_S); } else if (dSWeight >= MIN_ELEMENT_SUM && dOWeight < MIN_ELEMENT_SUM)// { Particle->SetChemicalType(GB_CHEMICAL_TYPE::CHE_S); } else if (dOWeight >= MIN_ELEMENT_SUM && dAlWeight >= MIN_ELEMENT_SUM) { Particle->SetChemicalType(GB_CHEMICAL_TYPE::CHE_Al); } else if (dOWeight >= MIN_ELEMENT_SUM && dSiWeight >= MIN_ELEMENT_SUM) { Particle->SetChemicalType(GB_CHEMICAL_TYPE::CHE_Si); } else if (dOWeight >= RICH_ELEMENT_SUM) { Particle->SetChemicalType(GB_CHEMICAL_TYPE::CHE_O); } else { Particle->SetChemicalType(GB_CHEMICAL_TYPE::INVALID); } return TRUE; } }