⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tabtoolsimulate.cpp

📁 这是关于飞机生存力计算软件
💻 CPP
📖 第 1 页 / 共 4 页
字号:
					nReturnCode = Simulate(DetonationVertex,
											TriMeshesWeightCenterVertex,
											fLengthOfDetonation,
											fLengthOfDPToWC,
											m_nYScanLinesSM,
											sMsg1,
											pUnimportantMeshNameArray,
											nUnimportantMeshesItems,
											pImportantMeshNameArray,
											nImportantMeshesItems);

					if(nReturnCode == -1)
					{
						//some error has rise
						bIsOK = FALSE;
						break;
					}

					if(nReturnCode == 3)
					{
						//This missile must miss the fighter
						fprintf(OutPutFile, "0.0 0.0 0.0\n");

						continue;
					}

					ExeFile = fopen("vul01.exe", "rb" );
					if(ExeFile == NULL)
					{
						AfxMessageBox("未找到单枚导弹仿真分析程序vul01.exe!");
						bIsOK = FALSE;
						break;
					}
					else
						fclose(ExeFile);

					memset(&StartupInfo, 0, sizeof(STARTUPINFO));
					StartupInfo.cb = sizeof(STARTUPINFO);
					StartupInfo.dwFlags = STARTF_USESHOWWINDOW;
					StartupInfo.wShowWindow = SW_HIDE;
					fSuccess = ::CreateProcess(NULL,
										"vul01.exe",
										NULL,
										NULL,
										FALSE,
										0,
										NULL,
										NULL,
										&StartupInfo,
										&ProcessInfo);
					if(fSuccess)
					{
						hProcess = ProcessInfo.hProcess;

						//Close the thread handle as soon as it is no longer needed!
						::CloseHandle(ProcessInfo.hThread);

						if(WaitForSingleObject(hProcess, INFINITE) != WAIT_FAILED)
						{
							//The process terminated
							::GetExitCodeProcess(hProcess, &dwExitCode);
						}

						//Close the process handle as soon as it is no longer needed
						CloseHandle(hProcess);
				
						OutPutFile1 = fopen("final01.dat", "rt" );
						if(OutPutFile1 == NULL)
						{
							AfxMessageBox("找不到数据文件final01.dat!");
							bIsOK = FALSE;
							break;
						}
				

						fscanf(OutPutFile1, "%f %f %f", &fAiv, &fP, &fP2);
						fclose(OutPutFile1);
						fprintf(OutPutFile, "%f %f %f\n", fAiv, fP, fP2);
					}
					else
					{
						AfxMessageBox("创建子进程失败!");
						bIsOK = FALSE;
						break;
					}
				}
				
				if(bIsOK == FALSE)break;
			}
			fclose(OutPutFile);
			if(bIsOK == FALSE)break;
		}

		//Update all views
		//pDoc->UpdateAllViews(NULL);
		
		SetCurrentDirectory(szCurDir);

		if(bIsOK == TRUE)
		{
			sMsg.Format("模拟结束,结果请查看数据文件final26_*.dat"); 
		}

		if(pUnimportantMeshNameArray != NULL)
			delete [] pUnimportantMeshNameArray;

		delete [] pImportantMeshNameArray;
	}
}

void CTabtoolSimulate::OnTabtoolSimulateMultimissiles() 
{
	// TODO: Add your control notification handler code here
	CSimulateView *pSimulateView;
	pSimulateView = (CSimulateView *)GetRenderView();

	AfxMessageBox((pSimulateView->GetDocument())->m_szStartDirectory);
}

int CTabtoolSimulate::Simulate(CVertex & DetonationVertex,
								CVertex & TriMeshesWeightCenterVertex,
								float fLengthOfDetonation,
								float fLengthOfDPToWC,
								int nYScanLines,
								const char *OutPutFileName,
								const CString * pUnimportantMeshNameArray,
								int nUnimportantMeshesItems,
								const CString * pImportantMeshNameArray,
								int nImportantMeshesItems) 
{
	CString sMsg;
	float fTemp;
	FILE* OutPutFile;
	OutPutFile  = fopen(OutPutFileName, "wt" );
	if(OutPutFile == NULL)
	{
		AfxMessageBox("写数据文件失败!");
		return(-1);
	}

	CSimulateDoc* pDoc = ((CSimulateView *)GetRenderView())->GetDocument();
	ASSERT_VALID(pDoc);

	//First of all we should compute the projection matrix
	float fCenterX, fCenterY, fCenterZ;
	float fXEye, fYEye, fZEye;
	float fXUpper, fYUpper, fZUpper;
	float fLengThOfNewX;
	CVector NewX, NewY, NewZ;
	CVector TempVector;
	CMatrix ProjectionMatrix(4, 4);
	CMatrix TempMatrix(4, 4);

	fXEye = DetonationVertex.m_fX;
	fYEye = DetonationVertex.m_fY;
	fZEye = DetonationVertex.m_fZ;

	fCenterX = TriMeshesWeightCenterVertex.m_fX;
	fCenterY = TriMeshesWeightCenterVertex.m_fY;
	fCenterZ = TriMeshesWeightCenterVertex.m_fZ;

	NewZ.m_fX = fXEye - fCenterX;
	NewZ.m_fY = fYEye - fCenterY;
	NewZ.m_fZ = fZEye - fCenterZ;
	NewZ.Normalize();

	//Select the original vector for the new oy vector in the 
	//projected plane, the sequence is (0.0, 1.0, 0.0)->
	//(1.0, 0.0, 0.0)->(0.0, 0.0, 1.0), just to avoid the 
	//projection error if the projected vector is a "zero"
	//vector!
	fXUpper = 0.0; fYUpper = 1.0; fZUpper = 0.0;

	NewX.m_fX = fXUpper;
	NewX.m_fY = fYUpper;
	NewX.m_fZ = fZUpper;
	NewX.CrossProduct(NewZ);
	fLengThOfNewX = NewX.fLength();
	if(fLengThOfNewX < 1.0e-8)
	{
		fXUpper = 1.0; fYUpper = 0.0; fZUpper = 0.0;
		NewX.m_fX = fXUpper;
		NewX.m_fY = fYUpper;
		NewX.m_fZ = fZUpper;
		NewX.CrossProduct(NewZ);
		fLengThOfNewX = NewX.fLength();
		if(fLengThOfNewX < 1.0e-8)
		{
			fXUpper = 0.0; fYUpper = 0.0; fZUpper = 1.0;
			NewX.m_fX = fXUpper;
			NewX.m_fY = fYUpper;
			NewX.m_fZ = fZUpper;
			NewX.CrossProduct(NewZ);
			fLengThOfNewX = NewX.fLength();
			if(fLengThOfNewX < 1.0e-8)
			{
				AfxMessageBox("严重投影错误!", MB_OK | MB_ICONSTOP);
				return(-1);
			}
		}
	}
	NewX.Normalize();

	NewY.m_fX = NewZ.m_fX;
	NewY.m_fY = NewZ.m_fY;
	NewY.m_fZ = NewZ.m_fZ;
	NewY.CrossProduct(NewX);
	NewY.Normalize();
	
	ProjectionMatrix(0, 0) = NewX.m_fX;
	ProjectionMatrix(1, 0) = NewY.m_fX;
	ProjectionMatrix(2, 0) = NewZ.m_fX;
	ProjectionMatrix(3, 0) = 0.0;

	ProjectionMatrix(0, 1) = NewX.m_fY;
	ProjectionMatrix(1, 1) = NewY.m_fY;
	ProjectionMatrix(2, 1) = NewZ.m_fY;
	ProjectionMatrix(3, 1) = 0.0;

	ProjectionMatrix(0, 2) = NewX.m_fZ;
	ProjectionMatrix(1, 2) = NewY.m_fZ;
	ProjectionMatrix(2, 2) = NewZ.m_fZ;
	ProjectionMatrix(3, 2) = 0.0;

	ProjectionMatrix(0, 3) = 0.0;
	ProjectionMatrix(1, 3) = 0.0;
	ProjectionMatrix(2, 3) = 0.0;
	ProjectionMatrix(3, 3) = 1.0;

	TempMatrix(0, 0) = 1.0;
	TempMatrix(1, 0) = 0.0;
	TempMatrix(2, 0) = 0.0;
	TempMatrix(3, 0) = 0.0;

	TempMatrix(0, 1) = 0.0;
	TempMatrix(1, 1) = 1.0;
	TempMatrix(2, 1) = 0.0;
	TempMatrix(3, 1) = 0.0;

	TempMatrix(0, 2) = 0.0;
	TempMatrix(1, 2) = 0.0;
	TempMatrix(2, 2) = 1.0;
	TempMatrix(3, 2) = 0.0;

	TempMatrix(0, 3) = -1.0 * fXEye;
	TempMatrix(1, 3) = -1.0 * fYEye;
	TempMatrix(2, 3) = -1.0 * fZEye;
	TempMatrix(3, 3) = 1.0;

	ProjectionMatrix.Multiply(TempMatrix);
	
	int Index = pDoc->GetNumTriMeshes();
	CTriMeshForIntersection * pTriMeshForIntersection = new CTriMeshForIntersection [Index];
	
	while(Index--)
		(pDoc->GetTriMesh(Index))->PreCalculateForIntersection(
		pTriMeshForIntersection[Index], ProjectionMatrix);

	//First we get the overall fXMin, fXMax, fYMin, fYMax 
	Index = pDoc->GetNumTriMeshes();
	float fXMin, fXMax, fYMin, fYMax;
	int i, j, k, m;

	fXMin = 1.0e8;
	fYMin = 1.0e8;
	fXMax = -1.0e8;
	fYMax = -1.0e8;
	for(i = 0; i < Index; i++)
	{
		if((pTriMeshForIntersection[i]).m_fXMin < fXMin)
			fXMin = (pTriMeshForIntersection[i]).m_fXMin;

		if((pTriMeshForIntersection[i]).m_fYMin < fYMin)
			fYMin = (pTriMeshForIntersection[i]).m_fYMin;

		if((pTriMeshForIntersection[i]).m_fXMax > fXMax)
			fXMax = (pTriMeshForIntersection[i]).m_fXMax;

		if((pTriMeshForIntersection[i]).m_fYMax > fYMax)
			fYMax = (pTriMeshForIntersection[i]).m_fYMax;
	}

	if(fYMax <  -1. * fLengthOfDetonation ||
		fYMin >  fLengthOfDetonation)
	{
		//If the missile miss the fighter
		delete [] pTriMeshForIntersection;
	
		//OutPut the sign 3 means that the missile miss the fighter
		fprintf(OutPutFile, "3,\n");
		fclose(OutPutFile);
		return(3);
	}

	BOOL bLocalProjection = FALSE;
	
	if(fYMax > fLengthOfDetonation)
	{
		fTemp = fLengthOfDetonation;
		bLocalProjection = TRUE;
	}
	else
		fTemp = fYMax;

	fYMax = fTemp;

	if(fYMin > -1.*fLengthOfDetonation)
		fTemp = fYMin;
	else
	{
		fTemp = -1.*fLengthOfDetonation;
		bLocalProjection = TRUE;
	}

	fYMin = fTemp;

	int nXScanLines;
	float fYStep = (fYMax - fYMin)/(float)nYScanLines;
	float fXStep;
	List<CScanIntersectionPoint>* pScanIntersectionPointList;
	pScanIntersectionPointList = new List<CScanIntersectionPoint>;
	Node<CLine>* pBoundaryLineNode;
	List<CSimulateArea>* pSimulateAreaList = new List<CSimulateArea>;
	List<CMiniArea>* pMiniAreaList = new List<CMiniArea>;
	CMiniArea MiniArea;
	Node<CSimulateArea>* pSimulateAreaNode;
	CSimulateArea SimulateArea;
	Node<CMiniArea>* pMiniAreaNode;
	CString sMsgTemp;

	//Now let's canculate the area
	//once a nYScanLines
	float fXScan, fYScan, fZScan, fZMax;
	float fT;
	CScanIntersectionPoint ScanIntersectionPoint;
	Node<CScanIntersectionPoint>* pScanIntersectionPointNode;
	Node<CScanIntersectionPoint>* pPreScanIntersectionPointNode;
	BOOL bInserted;

	m_ProgressBar.ShowWindow(SW_SHOWNORMAL);	
	m_ProgressBar.SetRange(0, nYScanLines);
	m_ProgressBar.SetStep(1);
	m_ProgressBar.SetPos(0);	
	for(i = 0; i < nYScanLines; i++)
	{
		fYScan = fYMin + i * fYStep + fYStep/2.0;
		pScanIntersectionPointList->ClearAllNodes();
		//once a TriMeshForIntersection
		for(j = 0; j < Index; j++)
		{
			pBoundaryLineNode = ((pTriMeshForIntersection[j]).m_pBoundaryLineList)->pGetHead();
			pBoundaryLineNode = pBoundaryLineNode->m_pNext;
			while(pBoundaryLineNode != NULL)
			{
				//First version do not think of the case 
				//((pBoundaryLineNode->m_Data).m_FirstVertex).m_fY = 
				//((pBoundaryLineNode->m_Data).m_SecondVertex).m_fY,
				//in this case the boundary line is parallel to the 
				//x axis ih the projected plane
				if(fabs(((pBoundaryLineNode->m_Data).m_SecondVertex).m_fY - 
						((pBoundaryLineNode->m_Data).m_FirstVertex).m_fY) > 0.000001)
				{
					fT = (fYScan - ((pBoundaryLineNode->m_Data).m_FirstVertex).m_fY)/
						(((pBoundaryLineNode->m_Data).m_SecondVertex).m_fY - ((pBoundaryLineNode->m_Data).m_FirstVertex).m_fY);

					if(fT > 0 && fT < 1)
					{
						//if there really exists an intersection 
						fXScan = (((pBoundaryLineNode->m_Data).m_SecondVertex).m_fX - ((pBoundaryLineNode->m_Data).m_FirstVertex).m_fX)*
							fT + ((pBoundaryLineNode->m_Data).m_FirstVertex).m_fX;

						fZScan = (((pBoundaryLineNode->m_Data).m_SecondVertex).m_fZ - ((pBoundaryLineNode->m_Data).m_FirstVertex).m_fZ)*
							fT + ((pBoundaryLineNode->m_Data).m_FirstVertex).m_fZ;

						ScanIntersectionPoint.m_fX = fXScan;
						ScanIntersectionPoint.m_fY = fYScan;
						ScanIntersectionPoint.m_fZ = fZScan;
						ScanIntersectionPoint.m_sName = (pTriMeshForIntersection[j]).m_sName;
					
						if(((pBoundaryLineNode->m_Data).m_SecondVertex).m_fY <
							((pBoundaryLineNode->m_Data).m_FirstVertex).m_fY)
							ScanIntersectionPoint.m_nFlag = UPTODOWN;
						else
							ScanIntersectionPoint.m_nFlag = DOWNTOUP;

						pScanIntersectionPointList->InsertNewNodeAtTail(ScanIntersectionPoint);
					}
				}
				pBoundaryLineNode = pBoundaryLineNode->m_pNext;
			}
		}
		pScanIntersectionPointList->SortLowToHigh();

		//Now we have get the ScanIntersectionPointList of all trimeshes for the current y scan line
		pScanIntersectionPointNode = pScanIntersectionPointList->pGetHead();
		pPreScanIntersectionPointNode = pScanIntersectionPointNode->m_pNext;
		if(pPreScanIntersectionPointNode != NULL)
		{
			pScanIntersectionPointNode = pPreScanIntersectionPointNode->m_pNext;
			while(pScanIntersectionPointNode != NULL)
			{
				nXScanLines = (int)(((pScanIntersectionPointNode->m_Data).m_fX - 
						(pPreScanIntersectionPointNode->m_Data).m_fX)/
						fYStep) + 1;


				fXStep = ((pScanIntersectionPointNode->m_Data).m_fX - 
						(pPreScanIntersectionPointNode->m_Data).m_fX)/
						(float)nXScanLines;

				for(k = 0; k < nXScanLines; k++)
				{
					fXScan = (pPreScanIntersectionPointNode->m_Data).m_fX + k * fXStep + fXStep/2.0;
					pMiniAreaList->ClearAllNodes();

					//calculate MiniAreaList per big "pixel"!
					for(m = 0; m < Index; m++)
					{
						if((pTriMeshForIntersection[m]).bIntersectPointByXY(fXScan, fYScan, fZMax))
						{
							//if current mesh has a miniarea

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -