#pragma once #include "stdafx.h" #include "GBFieldData.h" #include "CGBLevel.h" #include #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; } CString DoubleToCString(double d) { CString s; s.Format(_T("%.0lf"), d); return s; } CString IntToCString(int d) { CString s; s.Format(_T("%d"), d); return s; } } #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(); } void CGBFieldData::SetOTSParticleList(COTSParticleList& a_listParticles, BOOL a_bClear) { m_listOTSParticles = a_listParticles; } // cleanup void CGBFieldData::Cleanup() { } // initialization void CGBFieldData::Init() { // id m_nFrameId = -1; // A level m_pALevel = CGBLevelPtr(new CGBLevel(this, GB_CLASSIFY_TYPE::A_TYPE)); // B level m_pBLevel = CGBLevelPtr(new CGBLevel(this, GB_CLASSIFY_TYPE::B_TYPE)); // C level m_pCLevel = CGBLevelPtr(new CGBLevel(this, GB_CLASSIFY_TYPE::C_TYPE)); // D level m_pDLevel = CGBLevelPtr(new CGBLevel(this, GB_CLASSIFY_TYPE::D_TYPE)); // DSulfide level m_pDSulfidLevel = CGBLevelPtr(new CGBLevel(this, GB_CLASSIFY_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_listOTSParticles.empty()) { return; } COTSParticleList listBAndDParticles;// COTSParticleList listAparts; COTSParticleList listCparts; COTSParticleList listBparts; COTSParticleList listDparts; COTSParticleList listDSparts; // get all the all particles for each level for (auto pParticle : m_listOTSParticles) { // compute length width ratio if (pParticle->GetType() == OTS_PARTICLE_TYPE::INVALID)//here we take all the particles except Invalid. { continue; } if (pParticle->GetClassifyName() == _T("FeO"))//here we take all the particles except Invalid. { continue; } if (pParticle->GetClassifyName() == _T("SiC"))//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; } GB_CHEMICAL_TYPE nChemicalType = GBParticle::IdentifyPartChemicalType(pParticle); if (dLengthWidthRatio >= 3)//长宽比大于3的颗粒,根据化学元素不同,分为A类和C类 { //A or C class if (nChemicalType == GB_CHEMICAL_TYPE::CHE_S) { // A listAparts.push_back(pParticle); } else if (nChemicalType == GB_CHEMICAL_TYPE::CHE_O || nChemicalType== GB_CHEMICAL_TYPE::CHE_Si || nChemicalType == GB_CHEMICAL_TYPE::CHE_Al) { // C listCparts.push_back(pParticle); } } else//长宽比小于3的颗粒,有3种情况,一种是串条状的B类颗粒,一种是单独的D类颗粒,如果费雷特直径大于13则为DS类颗粒 { // B, or D or DS if (nChemicalType == GB_CHEMICAL_TYPE::CHE_S)//if it contains sulfide then it is a A particle. { listAparts.push_back(pParticle); } else { // B or D listBAndDParticles.push_back(pParticle); } } } //process A class CGBParticleList listAGBparts; ConnectStringParts(listAparts, listAGBparts); for (auto gbp : listAGBparts) { gbp->myType = GB_CLASSIFY_TYPE::A_TYPE; //计算颗粒宽度是属于细系粗系还是超尺寸 GB_WIDTH_TYPE wt = gbp->CaculateLevelWidth(GB_CLASSIFY_TYPE::A_TYPE); gbp->myWidth = wt; switch (wt) { case GB_WIDTH_TYPE::THIN: listAThinParticles.push_back(gbp); break; case GB_WIDTH_TYPE::WIDE: listAWideParticles.push_back(gbp); break; case GB_WIDTH_TYPE::SUPER: listASuperParticles.push_back(gbp); break; } } //process C class CGBParticleList listCGBparts; ConnectStringParts(listCparts, listCGBparts); //计算颗粒宽度是属于细系粗系还是超尺寸 for (auto gbp : listCGBparts) { gbp->myType = GB_CLASSIFY_TYPE::C_TYPE; GB_WIDTH_TYPE wt = gbp->CaculateLevelWidth(GB_CLASSIFY_TYPE::C_TYPE); gbp->myWidth = wt; switch (wt) { case GB_WIDTH_TYPE::THIN: listCThinParticles.push_back(gbp); break; case GB_WIDTH_TYPE::WIDE: listCWideParticles.push_back(gbp); break; case GB_WIDTH_TYPE::SUPER: listCSuperParticles.push_back(gbp); break; } } //process B and D class CGBParticleList listBorDGBparts; ConnectStringParts(listBAndDParticles, listBorDGBparts); for (auto pGBParticle : listBorDGBparts) { if (pGBParticle->myOTSParts.size()==1)//there's only one part ,it's a D part { /*if (pGBParticle.myPart->GetChemicalType() == GB_CHEMICAL_TYPE::CHE_O) {*/ pGBParticle->myType = GB_CLASSIFY_TYPE::D_TYPE;//no matter what chemical it contains,as long as the aspect ratio is less than 3,then it's a D type. //计算颗粒宽度是属于细系粗系还是超尺寸 GB_WIDTH_TYPE wt = pGBParticle->CaculateLevelWidth( GB_CLASSIFY_TYPE::D_TYPE); pGBParticle->myWidth = wt; switch (wt) { case GB_WIDTH_TYPE::THIN: listDThinParticles.push_back(pGBParticle); break; case GB_WIDTH_TYPE::WIDE: listDWideParticles.push_back(pGBParticle); break; case GB_WIDTH_TYPE::SUPER: listDSuperParticles.push_back(pGBParticle); break; } double dFeretDiameter = pGBParticle->GetFeretDiameter(); if (dFeretDiameter >= 13) { // DS listDSParticles.push_back(pGBParticle); } } else if (pGBParticle->myOTSParts.size() == 2)//there's only two parts,it's still D part { // split it into two GB D part for (auto p : pGBParticle->myOTSParts) { CGBParticlePtr gbp = CGBParticlePtr(new GBParticle()); gbp->myType = GB_CLASSIFY_TYPE::D_TYPE; gbp->myOTSParts.push_back(p); GB_WIDTH_TYPE wt = gbp->CaculateLevelWidth(GB_CLASSIFY_TYPE::D_TYPE); gbp->myWidth = wt; switch (wt) { case GB_WIDTH_TYPE::THIN: listDThinParticles.push_back(gbp); break; case GB_WIDTH_TYPE::WIDE: listDWideParticles.push_back(gbp); break; case GB_WIDTH_TYPE::SUPER: listDSuperParticles.push_back(gbp); break; } double dFeretDiameter = gbp->GetFeretDiameter(); if (dFeretDiameter >= 13) { // DS listDSParticles.push_back(gbp); } } } else if(pGBParticle->myOTSParts.size()>= 3) { pGBParticle->myType = GB_CLASSIFY_TYPE::B_TYPE; //计算颗粒宽度是属于细系粗系还是超尺寸 GB_WIDTH_TYPE wt = pGBParticle->CaculateLevelWidth( GB_CLASSIFY_TYPE::B_TYPE); pGBParticle->myWidth = wt; switch (wt) { case GB_WIDTH_TYPE::THIN: listBThinParticles.push_back(pGBParticle); break; case GB_WIDTH_TYPE::WIDE: listBWideParticles.push_back(pGBParticle); break; case GB_WIDTH_TYPE::SUPER: listBSuperParticles.push_back(pGBParticle); break; } } } } // caculate Level by method 2 void CGBFieldData::CategoryByMethod2() { COTSParticleList listBAndDParticles;// COTSParticleList listAparts; COTSParticleList listCparts; COTSParticleList listBparts; COTSParticleList listDparts; COTSParticleList listDsulparts; COTSParticleList listDSparts; if (m_listOTSParticles.empty()) { return; } // get all the all particles for each level for (auto pParticle : m_listOTSParticles) { if (pParticle->GetType() == OTS_PARTICLE_TYPE::INVALID)//here we take all the particles except Invalid. { continue; } if (pParticle->GetClassifyName() == _T("FeO"))//here we take all the particles except Invalid. { continue; } if (pParticle->GetClassifyName() == _T("SiC"))//here we take all the particles except Invalid. { continue; } //check the denominator is zero or not auto w = pParticle->GetDMin(); if (w == 0) { continue; } GB_CHEMICAL_TYPE nChemicalType = GBParticle::IdentifyPartChemicalType(pParticle); if (nChemicalType == GB_CHEMICAL_TYPE::CHE_S) { // A listAparts.push_back(pParticle); } else if (nChemicalType == GB_CHEMICAL_TYPE::CHE_Al) { // B listBparts.push_back(pParticle); } else if (nChemicalType == GB_CHEMICAL_TYPE::CHE_Si) { // C listCparts.push_back(pParticle); } } CGBParticleList listAGBPartsTemp; ConnectStringParts(listAparts, listAGBPartsTemp); CGBParticleList listBGBPartsTemp; ConnectStringParts(listBparts, listBGBPartsTemp); CGBParticleList listCGBPartsTemp; ConnectStringParts(listBparts, listCGBPartsTemp); for (auto p : listAGBPartsTemp) { if (p->myOTSParts.size() == 1)//it's a isolated part { //获取最小外接矩形的宽和高 auto p1 = p->myOTSParts[0]; double h = p1->GetDMax(); double w = p1->GetDMin(); double dLengthWidthRatio = h / w; if (dLengthWidthRatio < 1) { dLengthWidthRatio = 1 / dLengthWidthRatio; } if (dLengthWidthRatio < 3)//长宽比小于3的颗粒,且为孤立的颗粒,根据是否含硫化物,分为D类和DSulfide类,如果费雷特直径大于13 归为DS类 { double dFeretDiameter = p1->GetFeretDiameter(); if (dFeretDiameter >= 13) { // DS p->myType = GB_CLASSIFY_TYPE::DS_TYPE; listDSParticles.push_back(p); } else { p->myType = GB_CLASSIFY_TYPE::DSulfide_TYPE; auto wt = p->CaculateLevelWidth(GB_CLASSIFY_TYPE::DSulfide_TYPE); switch (wt) { case GB_WIDTH_TYPE::THIN: listDSulfideThinParticles.push_back(p); break; case GB_WIDTH_TYPE::WIDE: listDSulfideWideParticles.push_back(p); break; case GB_WIDTH_TYPE::SUPER: listDSulfideSuperParticles.push_back(p); break; } } } } else { p->myType = GB_CLASSIFY_TYPE::A_TYPE; auto wt = p->CaculateLevelWidth(GB_CLASSIFY_TYPE::A_TYPE); switch (wt) { case GB_WIDTH_TYPE::THIN: listAThinParticles.push_back(p); break; case GB_WIDTH_TYPE::WIDE: listAWideParticles.push_back(p); break; case GB_WIDTH_TYPE::SUPER: listASuperParticles.push_back(p); break; } } } for (auto p : listBGBPartsTemp) { if (p->myOTSParts.size() == 1)//it's a isolated part { //获取最小外接矩形的宽和高 auto p1 = p->myOTSParts[0]; double h = p1->GetDMax(); double w = p1->GetDMin(); double dLengthWidthRatio = h / w; if (dLengthWidthRatio < 1) { dLengthWidthRatio = 1 / dLengthWidthRatio; } if (dLengthWidthRatio < 3)//长宽比小于3的颗粒,且为孤立的颗粒,根据是否含硫化物,分为D类和DSulfide类,如果费雷特直径大于13 归为DS类 { double dFeretDiameter = p1->GetFeretDiameter(); if (dFeretDiameter >= 13) { // DS p->myType = GB_CLASSIFY_TYPE::DS_TYPE; listDSParticles.push_back(p); } else { p->myType = GB_CLASSIFY_TYPE::D_TYPE; auto wt = p->CaculateLevelWidth(GB_CLASSIFY_TYPE::D_TYPE); switch (wt) { case GB_WIDTH_TYPE::THIN: listDThinParticles.push_back(p); break; case GB_WIDTH_TYPE::WIDE: listDWideParticles.push_back(p); break; case GB_WIDTH_TYPE::SUPER: listDSuperParticles.push_back(p); break; } } } } else { p->myType = GB_CLASSIFY_TYPE::B_TYPE; auto wt = p->CaculateLevelWidth(GB_CLASSIFY_TYPE::B_TYPE); switch (wt) { case GB_WIDTH_TYPE::THIN: listBThinParticles.push_back(p); break; case GB_WIDTH_TYPE::WIDE: listBWideParticles.push_back(p); break; case GB_WIDTH_TYPE::SUPER: listASuperParticles.push_back(p); break; } } } for (auto p : listCGBPartsTemp) { if (p->myOTSParts.size() == 1)//it's a isolated part { //获取最小外接矩形的宽和高 auto p1 = p->myOTSParts[0]; double h = p1->GetDMax(); double w = p1->GetDMin(); double dLengthWidthRatio = h / w; if (dLengthWidthRatio < 1) { dLengthWidthRatio = 1 / dLengthWidthRatio; } if (dLengthWidthRatio < 3)//长宽比小于3的颗粒,且为孤立的颗粒,根据是否含硫化物,分为D类和DSulfide类,如果费雷特直径大于13 归为DS类 { double dFeretDiameter = p1->GetFeretDiameter(); if (dFeretDiameter >= 13) { // DS p->myType = GB_CLASSIFY_TYPE::DS_TYPE; listDSParticles.push_back(p); } else { p->myType = GB_CLASSIFY_TYPE::D_TYPE; auto wt = p->CaculateLevelWidth(GB_CLASSIFY_TYPE::D_TYPE); switch (wt) { case GB_WIDTH_TYPE::THIN: listDThinParticles.push_back(p); break; case GB_WIDTH_TYPE::WIDE: listDWideParticles.push_back(p); break; case GB_WIDTH_TYPE::SUPER: listDSuperParticles.push_back(p); break; } } } } else { p->myType = GB_CLASSIFY_TYPE::C_TYPE; auto wt = p->CaculateLevelWidth(GB_CLASSIFY_TYPE::C_TYPE); switch (wt) { case GB_WIDTH_TYPE::THIN: listCThinParticles.push_back(p); break; case GB_WIDTH_TYPE::WIDE: listCWideParticles.push_back(p); break; case GB_WIDTH_TYPE::SUPER: listCSuperParticles.push_back(p); break; } } } } // caculate Level by ASTM void CGBFieldData::CategoryByASTM() { // according to the shape if (m_listOTSParticles.empty()) { return; } this->CategoryByMethod1(); } // caculate Level by DIN void CGBFieldData::CaculateLevelDIN(COTSParticleList listParticle) { // according to the shape if (listParticle.empty()) { return; } COTSParticleList listBAndDParticles;// listBAndDParticles.clear(); // get all the all particles for each level for (auto pParticle : listParticle) { // compute length width ratio if (pParticle->GetType() == OTS_PARTICLE_TYPE::INVALID)//here we take all the particles except Invalid. { continue; } 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; } GB_CHEMICAL_TYPE nChemicalType = GBParticle::IdentifyPartChemicalType(pParticle); CGBParticlePtr gbp = CGBParticlePtr(new GBParticle()); gbp->myOTSParts.push_back(pParticle); if (dLengthWidthRatio >= 3)//长宽比大于3的颗粒,根据化学元素不同,分为A类和C类 { //A or C class if (nChemicalType == GB_CHEMICAL_TYPE::CHE_S) { // A //计算颗粒宽度是属于细系粗系还是超尺寸 GB_WIDTH_TYPE wt = gbp->CaculateLevelWidth(GB_CLASSIFY_TYPE::A_TYPE); if (wt == GB_WIDTH_TYPE::THIN || wt == GB_WIDTH_TYPE::WIDE || wt == GB_WIDTH_TYPE::SUPER) { listAThinParticles.push_back(gbp); } } else if (nChemicalType == GB_CHEMICAL_TYPE::CHE_O) { // C //计算颗粒宽度是属于细系粗系还是超尺寸 GB_WIDTH_TYPE wt = gbp->CaculateLevelWidth( GB_CLASSIFY_TYPE::C_TYPE); if (wt == GB_WIDTH_TYPE::THIN || wt == GB_WIDTH_TYPE::WIDE || wt == GB_WIDTH_TYPE::SUPER) { listAThinParticles.push_back(gbp); } } } else//长宽比小于3的颗粒,有3种情况,一种是串条状的B类颗粒,一种是单独的D类颗粒,如果费雷特直径大于13则为DS类颗粒 { // B, or D or DS double dFeretDiameter = pParticle->GetFeretDiameter(); if (dFeretDiameter >= 13) { // DS listDSParticles.push_back(gbp); } else { // B or D listBAndDParticles.push_back(pParticle); } } } CGBParticleList BorDGBParts; ConnectStringParts(listBAndDParticles, BorDGBParts); for (auto pGBParticle : BorDGBParts) { // check if the particle is alone if (pGBParticle->myOTSParts.size()==1) { pGBParticle->myType = GB_CLASSIFY_TYPE::D_TYPE; //计算颗粒宽度是属于细系粗系还是超尺寸 GB_WIDTH_TYPE wt = pGBParticle->CaculateLevelWidth( GB_CLASSIFY_TYPE::D_TYPE); if (wt == GB_WIDTH_TYPE::THIN || wt == GB_WIDTH_TYPE::WIDE || wt == GB_WIDTH_TYPE::SUPER) { listDThinParticles.push_back(pGBParticle); } } else//找到了相邻接的颗粒,不是孤立的则为B类 { pGBParticle->myType = GB_CLASSIFY_TYPE::B_TYPE;//把类型设为有效类型 //计算颗粒宽度是属于细系粗系还是超尺寸 GB_WIDTH_TYPE wt = pGBParticle->CaculateLevelWidth( GB_CLASSIFY_TYPE::B_TYPE); if (wt == GB_WIDTH_TYPE::THIN || wt == GB_WIDTH_TYPE::WIDE || wt == GB_WIDTH_TYPE::SUPER) { listBThinParticles.push_back(pGBParticle); } } } } void CGBFieldData::ConnectStringParts(COTSParticleList listParticle, CGBParticleList& listGBParticle) { class StringPart; typedef std::shared_ptr StringPartPtr; typedef std::vector listStringPart; class StringPart { public: StringPart(COTSParticlePtr p) { myPart = p; connectParticles .clear(); ifMerged = false; } COTSParticlePtr myPart; listStringPart connectParticles;//used to merge particles BOOL ifMerged; }; listStringPart listStringparts; for (auto p : listParticle) { listStringparts.push_back(StringPartPtr(new StringPart(p))); } for (auto pParticle : listStringparts) { //check if the particle is alone auto adjacentPart = find_if(listStringparts.begin(), listStringparts.end(), [pParticle](StringPartPtr pstringParticle) { //the conditional particle COTSRect rectParticle = pParticle->myPart->GetOTSRect(); CPoint ptParticleCenter = rectParticle.GetCenterPoint(); int Bottom = rectParticle.GetBottomRight().y; int Top = rectParticle.GetTopLeft().y; //the current iteration particle COTSRect rectBCurParticle = pstringParticle->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(Bottom= Top) //current particle is on the below { dd = BottomB - Top; if (dd < 40) { return true; } } else if (BottomB < Top && BottomB> Bottom) { return true; } } return false; }); if (adjacentPart == listStringparts.end())//没找到 { } else//找到了相邻接的颗粒, { pParticle->connectParticles.push_back( *adjacentPart); adjacentPart->get()->connectParticles .push_back( pParticle); } } //BFS all these string parts queue partque; for (auto pParticle : listStringparts) { if (!pParticle->ifMerged) { CGBParticlePtr gbpart = CGBParticlePtr(new GBParticle()); partque.push(pParticle); while (partque.size()>0) { StringPartPtr currpart = partque.front(); if (!currpart->ifMerged) { gbpart->myOTSParts.push_back(currpart->myPart); currpart->ifMerged = true; for (auto connP : currpart->connectParticles) { partque.push(connP); } } partque.pop(); } listGBParticle.push_back(gbpart); } } } // caculate Level Width BOOL CGBFieldData::CaculateLevelThinWidth(COTSParticleList& a_listParticles, GB_CLASSIFY_TYPE a_nLevel) { if (a_listParticles.empty()) { return FALSE; } double dMin = 2, dMax = 0; switch ((int)a_nLevel) { case (int)GB_CLASSIFY_TYPE::A_TYPE: dMax = 4; break; case (int)GB_CLASSIFY_TYPE::B_TYPE: dMax = 9; break; case (int)GB_CLASSIFY_TYPE::C_TYPE: dMax = 5; break; case (int)GB_CLASSIFY_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; } BOOL CGBFieldData::CaculateLevelFatWidth(COTSParticleList& a_listParticles, GB_CLASSIFY_TYPE a_nLevel) { if (a_listParticles.empty()) { return FALSE; } double dMin = 0, dMax = 0; switch ((int)a_nLevel) { case (int)GB_CLASSIFY_TYPE::A_TYPE: dMin = 4; dMax = 12; break; case (int)GB_CLASSIFY_TYPE::B_TYPE: dMin = 9; dMax = 15; break; case (int)GB_CLASSIFY_TYPE::C_TYPE: dMin = 5; dMax = 12; break; case (int)GB_CLASSIFY_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_CLASSIFY_TYPE a_nLevel) { if (a_listParticles.empty()) { return FALSE; } double dMin = 0; switch ((int)a_nLevel) { case (int)GB_CLASSIFY_TYPE::A_TYPE: dMin = 12; break; case (int)GB_CLASSIFY_TYPE::B_TYPE: dMin = 15; break; case (int)GB_CLASSIFY_TYPE::C_TYPE: dMin = 12; break; case (int)GB_CLASSIFY_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; } std::string CGBFieldData::GetGBGradeString() { std::string grdStr; CString Astring = _T("A:") + GetGradeString(m_pALevel->GetThinGrade()) + _T(" ") + GetGradeString(m_pALevel->GetWideGrade()) + _T(" ") + GetGradeString(m_pALevel->GetSuperGrade()) + _T(" "); CString Bstring = _T("B:") + GetGradeString(m_pBLevel->GetThinGrade()) + _T(" ") + GetGradeString(m_pBLevel->GetWideGrade()) + _T(" ") + GetGradeString(m_pBLevel->GetSuperGrade()) + _T(" "); CString Cstring = _T("C:") + GetGradeString(m_pCLevel->GetThinGrade()) + _T(" ") + GetGradeString(m_pCLevel->GetWideGrade()) + _T(" ") + GetGradeString(m_pCLevel->GetSuperGrade()) + _T(" "); CString Dstring = _T("D:") + GetGradeString(m_pDLevel->GetThinGrade())+_T(" ") + GetGradeString(m_pDLevel->GetWideGrade()) +_T(" ") + GetGradeString(m_pDLevel->GetSuperGrade()) +_T(" "); if (calcuType == GB_METHODE_TYPE::METHODE_2) { CString DSulstring = _T("DSulfide:") + GetGradeString(GetDSulfideLevel()->GetThinGrade()) + _T(" ") + GetGradeString(GetDSulfideLevel()->GetWideGrade()) + _T(" ") + GetGradeString(GetDSulfideLevel()->GetSuperGrade()); grdStr= std::string((Astring + Bstring + Cstring + Dstring + DSulstring).GetBuffer()); } else { grdStr= std::string((Astring + Bstring + Cstring + Dstring ).GetBuffer()); } return grdStr; } std::string CGBFieldData::GetGBGradeDetail() { std::string grdStr; CString Astring = _T("A:") + GetGradeString(m_pALevel->GetThinGrade()) + _T("(") + DoubleToCString(m_pALevel->GetThinLength()) + _T(")") + _T(" ") + GetGradeString(m_pALevel->GetWideGrade()) + _T("(") + DoubleToCString(m_pALevel->GetWideLength()) + _T(")") + _T(" ") + GetGradeString(m_pALevel->GetSuperGrade()) + _T("(") + DoubleToCString(m_pALevel->GetSuperLength()) + _T(")") + _T(" "); CString Bstring = _T("B:") + GetGradeString(m_pBLevel->GetThinGrade()) + _T("(") + DoubleToCString(m_pBLevel->GetThinLength()) + _T(")") + _T(" ") + GetGradeString(m_pBLevel->GetWideGrade()) + _T("(") + DoubleToCString(m_pBLevel->GetWideLength()) + _T(")") + _T(" ") + GetGradeString(m_pBLevel->GetSuperGrade()) + _T("(") + DoubleToCString(m_pBLevel->GetSuperLength()) + _T(")") + _T(" "); CString Cstring = _T("C:") + GetGradeString(m_pCLevel->GetThinGrade()) + _T("(") + DoubleToCString(m_pCLevel->GetThinLength()) + _T(")") + _T(" ") + GetGradeString(m_pCLevel->GetWideGrade()) + _T("(") + DoubleToCString(m_pCLevel->GetWideLength()) + _T(")") + _T(" ") + GetGradeString(m_pCLevel->GetSuperGrade()) + _T("(") + DoubleToCString(m_pCLevel->GetSuperLength()) + _T(")") + _T(" "); CString Dstring = _T("D:") + GetGradeString(m_pDLevel->GetThinGrade()) + _T("(") + DoubleToCString(m_pDLevel->GetThinLength()) + _T(")") + _T(" ") + GetGradeString(m_pDLevel->GetWideGrade()) + _T("(") + DoubleToCString(m_pDLevel->GetWideLength()) + _T(")") + _T(" ") + GetGradeString(m_pDLevel->GetSuperGrade()) + _T("(") + DoubleToCString(m_pDLevel->GetSuperLength()) + _T(")") + _T(" "); if (calcuType == GB_METHODE_TYPE::METHODE_2) { CString DSulstring = _T("DSulfide:") + GetGradeString(GetDSulfideLevel()->GetThinGrade()) + _T(" ") + GetGradeString(GetDSulfideLevel()->GetWideGrade()) + _T(" ") + GetGradeString(GetDSulfideLevel()->GetSuperGrade()); grdStr = std::string((Astring + Bstring + Cstring + Dstring + DSulstring).GetBuffer()); } else { grdStr = std::string((Astring + Bstring + Cstring + Dstring).GetBuffer()); } return grdStr; } 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; } }