コード例 #1
0
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;
}
コード例 #2
0
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);
				}
			}
		}
	}
}
コード例 #3
0
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();		
}