📄 tabtoolsimulate.cpp
字号:
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 + -