#pragma once #include "stdafx.h" #include "GBFieldData.h" #include "CGBLevel.h" #include namespace OTSGBCalculate { using namespace std; using namespace OTSDATA; namespace { CString GetGradeString(GB_GRADE_TYPE grade) { CString gr; switch (grade) { case GB_GRADE_TYPE::POINT_0_0: gr = _T("0"); break; case GB_GRADE_TYPE::POINT_0_5: gr = _T("0.5"); break; case GB_GRADE_TYPE::POINT_1_0: gr = _T("1.0"); break; case GB_GRADE_TYPE::POINT_1_5: gr = _T("1.5"); break; case GB_GRADE_TYPE::POINT_2_0: gr = _T("2.0"); break; case GB_GRADE_TYPE::POINT_2_5: gr = _T("2.5"); break; case GB_GRADE_TYPE::POINT_3_0: gr = _T("3.0"); break; case GB_GRADE_TYPE::POINT_3_5: gr = _T("3.5"); break; case GB_GRADE_TYPE::POINT_4_0: gr = _T("4.0"); break; case GB_GRADE_TYPE::POINT_4_5: gr = _T("4.5"); break; case GB_GRADE_TYPE::POINT_5_0: gr = _T("5.0"); break; default: break; } return gr; } } #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 < 15 )//recognize these two particle as in the same vertical line. { if (Bottom > TopB)//current particle is on the above { dd = Bottom - TopB; if (dd < 40)//recognize these two particle as 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 { if ((*adjacentPart)->GetType() != OTS_PARTCLE_TYPE::INVALID) { return *adjacentPart; } else { return nullptr; } } } #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()));//&& } CGBFieldData::~CGBFieldData() // detractor { Cleanup(); } // 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)); // 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())); m_nFrameId = a_oSource.m_nFrameId; } // caculate Level by method 1 void CGBFieldData::CategoryByMethod1() { // 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 if (pParticle->GetType() == OTS_PARTICLE_TYPE::INVALID)//here we take all the particles except Invalid. { continue; } auto w = pParticle->GetDMin(); if (w == 0) { continue; } //获取最大长度和最小宽度 double h = pParticle->GetDMax(); 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 GBParticle gbP = GBParticle(pParticle, GB_LEVEL_TYPE::INVALID, GB_WIDTH_TYPE::INVALID); //不能确定是B或D,先设为INVALID listBAndDParticles.push_back(gbP); } } } } int n = listDSParticles.size(); 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 < 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())//没找到 { 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::CategoryByMethod2() { vector listABCParticles;// listABCParticles.clear(); if (m_listParticles.empty()) { return; } // get all the all particles for each level for (auto pParticle : m_listParticles) { if (pParticle->GetType() == OTS_PARTICLE_TYPE::INVALID)//here we take all the particles except Invalid. { continue; } //check the denominator is zero or not auto w = pParticle->GetDMin(); if (w == 0) { continue; } //获取最小外接矩形的宽和高 double h = pParticle->GetDMax(); 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 is a isolated particle. { 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 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::CategoryByASTM() { // 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 if (pParticle->GetType() == OTS_PARTICLE_TYPE::INVALID)//here we take all the particles except Invalid. { continue; } auto w = pParticle->GetDMin(); if (w == 0) { continue; } //获取最大长度和最小宽度 double h = pParticle->GetDMax(); 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 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 if (pParticle->GetType() != OTS_PARTICLE_TYPE::INVALID)//here we take all the particles { 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; } std::string CGBFieldData::GetGBGradeString() { CString Astring = _T("A:") + GetGradeString(GetALevel()->GetThinGrade()) + _T(" ") + GetGradeString(GetALevel()->GetWideGrade()) + _T(" ") + GetGradeString(GetALevel()->GetSuperGrade()) + _T(" "); CString Bstring = _T("B:") + GetGradeString(GetBLevel()->GetThinGrade()) + _T(" ") + GetGradeString(GetBLevel()->GetWideGrade()) + _T(" ") + GetGradeString(GetBLevel()->GetSuperGrade()) + _T(" "); CString Cstring = _T("C:") + GetGradeString(GetCLevel()->GetThinGrade()) + _T(" ") + GetGradeString(GetCLevel()->GetWideGrade()) + _T(" ") + GetGradeString(GetCLevel()->GetSuperGrade()) + _T(" "); CString Dstring = _T("D:") + GetGradeString(GetDLevel()->GetThinGrade()) + _T(" ") + GetGradeString(GetDLevel()->GetWideGrade()) + _T(" ") + GetGradeString(GetDLevel()->GetSuperGrade()) + _T(" "); CString DSulstring = _T("DSulfide:") + GetGradeString(GetDSulfideLevel()->GetThinGrade()) + _T(" ") + GetGradeString(GetDSulfideLevel()->GetWideGrade()) + _T(" ") + GetGradeString(GetDSulfideLevel()->GetSuperGrade()) ; return std::string((Astring + Bstring + Cstring + Dstring + DSulstring).GetBuffer()); } GB_GRADE_TYPE CGBFieldData::GetGBTopGrade() { GB_GRADE_TYPE gr = GetALevel()->GetThinGrade(); gr = std::max(gr, GetALevel()->GetWideGrade()); gr = std::max(gr, GetALevel()->GetSuperGrade()); gr = std::max(gr, GetBLevel()->GetThinGrade()); gr = std::max(gr, GetBLevel()->GetWideGrade()); gr = std::max(gr, GetBLevel()->GetSuperGrade()); gr = std::max(gr, GetCLevel()->GetThinGrade()); gr = std::max(gr, GetCLevel()->GetWideGrade()); gr = std::max(gr, GetCLevel()->GetSuperGrade()); gr = std::max(gr, GetDLevel()->GetThinGrade()); gr = std::max(gr, GetDLevel()->GetWideGrade()); gr = std::max(gr, GetDLevel()->GetSuperGrade()); gr = std::max(gr, GetDSulfideLevel()->GetThinGrade()); gr = std::max(gr, GetDSulfideLevel()->GetWideGrade()); gr = std::max(gr, GetDSulfideLevel()->GetSuperGrade()); return gr; } }