bool JPSPlusPathFinder::TraversalNeighbours(const Cell* currentCell, const Cell* goalCell) { PathNode& pathNode = mPathNodes[currentCell->Id()]; if (!pathNode.PrevCell) { bool nonblock[9]; char direction; for (direction = 0; direction <= JPSPlusPathFinder::MaxDirection; direction += 2) { const Cell* nextCell = NextWalkableCell(currentCell, (Direction)direction); RETURN_TRUE_IF(AddNeighbors(currentCell, nextCell, goalCell, direction)) nonblock[direction] = nextCell ? 1 : 0; } nonblock[8] = nonblock[0]; for (direction = 1; direction <= JPSPlusPathFinder::MaxDirection && nonblock[direction - 1] && nonblock[direction + 1]; direction += 2) { const Cell* next_cell = NextWalkableCell(currentCell, (Direction)direction); RETURN_TRUE_IF(AddNeighbors(currentCell, next_cell, goalCell, direction)); } } else { if (IsDirectionDiagonal(pathNode.PrevDirection)) /*diagonal*/ { /* natural neighbor */ const Cell* nextCell1 = NextWalkableCell(currentCell, pathNode.PrevDirection); RETURN_TRUE_IF(AddNeighbors(currentCell, nextCell1, goalCell, pathNode.PrevDirection)); const Cell* nextCell2 = NextWalkableCell(currentCell, (Direction)(pathNode.PrevDirection + 1)); RETURN_TRUE_IF(AddNeighbors(currentCell, nextCell2, goalCell, pathNode.PrevDirection + 1)); const Cell* nextCell3 = NextWalkableCell(currentCell, pathNode.PrevDirection - 1); RETURN_TRUE_IF(AddNeighbors(currentCell, nextCell3, goalCell, pathNode.PrevDirection - 1)); } else/*straight*/ { /* natural neighbor */ const Cell* nextCell1 = NextWalkableCell(currentCell, pathNode.PrevDirection); RETURN_TRUE_IF(AddNeighbors(currentCell, nextCell1, goalCell, pathNode.PrevDirection)); /* forced neighbor */ const Cell* nextCell2 = NextWalkableCell(currentCell, pathNode.PrevDirection + 3); const Cell* nextCell3 = nextCell2 ? nullptr : NextWalkableCell(currentCell, pathNode.PrevDirection + 2); RETURN_TRUE_IF(AddNeighbors(currentCell, nextCell3, goalCell, pathNode.PrevDirection + 2)); const Cell* nextCell4 = !(nextCell3 && nextCell1) ? nullptr : NextWalkableCell(currentCell, pathNode.PrevDirection + 1); RETURN_TRUE_IF(AddNeighbors(currentCell, nextCell4, goalCell, pathNode.PrevDirection + 1)); /* forced neighbor */ const Cell* nextCell5 = NextWalkableCell(currentCell, pathNode.PrevDirection + 5); const Cell* nextCell6 = nextCell5 ? nullptr : NextWalkableCell(currentCell, pathNode.PrevDirection + 6); RETURN_TRUE_IF(AddNeighbors(currentCell, nextCell6, goalCell, pathNode.PrevDirection + 6)); const Cell* nextCell7 = !(nextCell6 && nextCell1) ? nullptr : NextWalkableCell(currentCell, pathNode.PrevDirection + 7); RETURN_TRUE_IF(AddNeighbors(currentCell, nextCell7, goalCell, pathNode.PrevDirection + 7)); } } return false; }
void CToolCervicales::AddNeighbors(CDib * m_Dib, CList<CPoint, CPoint&>& i_List, CPoint& i_Point, int i_Direction){ i_List.AddTail(i_Point); CPoint n_Point; for (int i=0;i<8;i+=2){ if ((i + 4 == i_Direction)||(i - 4 == i_Direction)) continue; n_Point = GetNPoint(i_Point, i); if ((n_Point.x >= 0)&&(n_Point.x < m_Dib->GetWidth())) { if ((n_Point.y >= 0)&&(n_Point.y < m_Dib->GetHeight())) { if ((m_Dib->GetPixel(n_Point.x, n_Point.y) == 0)&&(FindInList(i_List, n_Point) == -1)) { AddNeighbors(m_Dib, i_List, n_Point, i); } } } } }
void CToolCervicales::TraceContour(CDib * m_Dib, CRxDoc * i_Document) { theApp.ShowProgress("Tracing contour, please be patient."); CList<CPoint, CPoint&> c_List; CList<CPoint, CPoint&> total_List; CList<CPoint, CPoint&> full_List[VERTEBRE_COUNT]; int full_ListCount = 0; /* locate any first black pixel */ CSize m_DibSize = m_Dib->GetDimensions(); CPoint l_Point; POSITION c_Pos; int x, y; for (x=0;x<m_DibSize.cx;x++) { theApp.SetProgress(x * 100 / m_DibSize.cx); for (y=0;y<m_DibSize.cy;y++) { if (m_Dib->GetPixel(x, y) == 0) { l_Point = CPoint(x,y); if (FindInList(total_List, l_Point) == -1) { c_List.RemoveAll(); AddNeighbors(m_Dib, c_List, l_Point, 6); // copy to full list c_Pos = c_List.GetHeadPosition(); while (c_Pos != NULL) total_List.AddTail(c_List.GetNext(c_Pos)); // find the smallest list int f_Min = full_ListCount; if (full_ListCount == VERTEBRE_COUNT) { f_Min = 0; //double f_Distance=0; for (int l=0;l<full_List[f_Min].GetCount()-1;l++) f_Distance+=CAVector::Distance(full_List[f_Min].GetAt(full_List[f_Min].FindIndex(l)), full_List[f_Min].GetAt(full_List[f_Min].FindIndex(l+1))); for (int i=1;i<VERTEBRE_COUNT;i++) { //double i_Distance=0; //for (int l=0;l<full_List[i].GetCount()-1;l++) i_Distance+=CAVector::Distance(full_List[i].GetAt(full_List[i].FindIndex(l)), full_List[i].GetAt(full_List[i].FindIndex(l+1))); if (full_List[i].GetCount() < full_List[f_Min].GetCount()) //if (i_Distance < f_Distance) f_Min = i; } } else full_ListCount++; // copy to array of lists full_List[f_Min].RemoveAll(); c_Pos = c_List.GetHeadPosition(); while (c_Pos != NULL) full_List[f_Min].AddTail(c_List.GetNext(c_Pos)); //TraceContourTRACER(m_Dib, l_Point, c_List); } } } } /* Segmentation */ if (full_ListCount >= REAL_VERTEBRE_COUNT) { m_Dib->Cnv24Bit(); m_Dib->Invert(); CAVector AVectors[VERTEBRE_COUNT]; CAVector RealVectors[REAL_VERTEBRE_COUNT]; int l, k; for (l=0; l<full_ListCount;l++) { AVectors[l] = SegmentationGlob(m_Dib, i_Document, full_List[l]); AVectors[l].RecalcDistance(); //break; CString Msg; Msg.Format("Segmentation for object %d done.", l); theApp.SetProgress(Msg); } /* remove vectors of minimal length */ for (l=0;l<REAL_VERTEBRE_COUNT;l++) { int MaxIndex = 0; for (k=1;k<full_ListCount;k++) { if (AVectors[k].GetSize() && (AVectors[k].GetDistance() > AVectors[MaxIndex].GetDistance())) MaxIndex = k; } if (AVectors[MaxIndex].GetSize()){ //i_Document->Add(AVectors[MaxIndex]); RealVectors[l] = AVectors[MaxIndex]; AVectors[MaxIndex].RemoveAll(); AVectors[MaxIndex].RecalcDistance(); } } /* create a vector of leftmost points only */ CAVector FrontVector; int l_Pos, s_Pos; for (l=0;l<REAL_VERTEBRE_COUNT;l++) { // find the leftmost point l_Pos = 0; for (k=1;k<RealVectors[l].GetSize();k++) if (RealVectors[l].GetAt(k).x < RealVectors[l].GetAt(l_Pos).x) l_Pos = k; FrontVector.Add(RealVectors[l].GetAt(l_Pos)); // find the second leftmost point s_Pos = 0; for (k=1;k<RealVectors[l].GetSize();k++) if ((RealVectors[l].GetAt(k).x < RealVectors[l].GetAt(s_Pos).x)&&(k!=l_Pos)) s_Pos = k; if (s_Pos != l_Pos) FrontVector.Add(RealVectors[l].GetAt(s_Pos)); } FrontVector.SortY(); while (FrontVector.GetSize() < 14) FrontVector.Add(CPoint(FrontVector[FrontVector.GetSize()-1].x + 5, FrontVector[FrontVector.GetSize()-1].y + 5)); i_Document->Add(FrontVector); } else MessageBox(::GetFocus(), "Insufficient trace zones detected!", "Cervicales Tracer Error", MB_OK | MB_ICONERROR); theApp.HideProgress(); }