📄 mainfrm.cpp
字号:
}
//状态栏进度条启动
// m_wndStatusBar.SetViewProgress(true);
// m_wndStatusBar.StartRun();
}
DWORD WINAPI CMainFrame::SimulateProc()
{
CSimulateView* pView;
SimulateViewList* pList;
int i=m_nRandomSimulateNum-1;
CString strCaption;
int nRandomSimulateNum;
nRandomSimulateNum=m_nRandomSimulateNum;
// while(!m_pRandomSimulateView[i]->m_bStop)
// {
for(i=0;i<nRandomSimulateNum;i++)
{
if(m_bStop==true)
break;
if(!m_bIsUseFirst)
{
//创建新视图
pView=new CSimulateView;
pView->Create(NULL,NULL,AFX_WS_DEFAULT_VIEW,rectDefault,this,AFX_IDW_PANE_FIRST+1);
pView->OnInitialUpdate();
//创建尾节点
pList=(SimulateViewList*)malloc(sizeof(CSimulateView));
pList->pNext=NULL;
pList->pSimulateView=pView;
m_pSimulatingView=pView;
// m_nCurViewID+=i+m_nSimulateNum;
pList->nIndex=i+m_nSimulateNum;
//连接此节点
m_pSimulateViewListHead->pTail->pNext=pList;
//更改尾节点
m_pSimulateViewListHead->pTail=pList;
//插入一项
strCaption.Format("随机模拟(%d)",i+1+m_nSimulateNum);
m_wndWorkSpaceBar.m_wndOutlookBar.InsertItem(0,i,strCaption,0,0);
m_wndWorkSpaceBar.m_wndOutlookBar.UpdateWindow();
}
else
m_pSimulatingView=m_pSimulateViewListHead->pTail->pSimulateView;
this->ChangeView(0,i+m_nSimulateNum);
//链表当前指针后移
m_pSimulateViewList=m_pSimulateViewList->pNext;
// SingleSimulate();
SingleSimulateProc();
// m_pSimulateViewList->pTail->pSimulateView->SingleSimulate(m_SetParam);
m_bIsUseFirst=false;
}
m_nSimulateNum+=m_nRandomSimulateNum;
return 0;
}
void CMainFrame::SingleSimulate()
{
m_bStop =false;
DWORD dwThreadID;
DWORD (WINAPI CMainFrame:: *p1)() =SingleSimulateProc;
DWORD (WINAPI *p2)(LPVOID) = NULL;
memcpy(&p2, &p1, sizeof(p1));
// Be sure to pass "this" parameter to the thread procedure.
m_hThread = ::CreateThread(NULL, 0, p2, this, 0, &dwThreadID);
if(m_hThread == NULL)
{
MessageBox("创建线程时出现错误!","嗅探",MB_ICONINFORMATION);
return;
}
//依次模拟长短半轴
/* for(m_fCurLAxis=m_fLAxisFrom;m_fCurLAxis<=80;m_fCurLAxis+=m_fLAxisAdd)
for(m_fCurSAxis=Max(m_fSAxisFrom,(float)sqrt(2*m_fCurLAxis*m_fObjRadius-m_fObjRadius*m_fObjRadius));m_fCurSAxis<m_fCurLAxis;m_fCurSAxis+=m_fSAxisAdd)
{
//判断当前线程数是否超过最大线程数,是则空循环
while(m_nCurThreadNum >= m_nMaxThreadNum)
{};
//线程计数加一
m_CriticalSection.Lock();
m_nCurThreadNum++;
m_CriticalSection.Unlock();
//开始线程
// AfxBeginThread(TestThread, (LPVOID)param);
m_bStop =false;
DWORD dwThreadID;
DWORD (WINAPI CMainFrame:: *p1)() =SimulateProc;
DWORD (WINAPI *p2)(LPVOID) = NULL;
memcpy(&p2, &p1, sizeof(p1));
// Be sure to pass "this" parameter to the thread procedure.
m_hThread = ::CreateThread(NULL, 0, p2, this, 0, &dwThreadID);
if(m_hThread == NULL)
{
MessageBox("创建线程时出现错误!","嗅探",MB_ICONINFORMATION);
return;
}
}
//判断所有线程是否结束,否则空循环等待
while(m_nCurThreadNum >0)
{};*/
}
//对于当前的长半轴和短半轴随机生成已经给出的光子数并模拟
DWORD WINAPI CMainFrame::SingleSimulateProc()
{
Point pCutPoint; //交点
Point pTempPoint; //临时交点
Line pReflectLine; //反射直线
int nReflectCount; //已反射次数
bool IsDie=false; //光子是否消灭
bool IsSorb=false; //光子是否被吸收
//清除最大记录
m_MaxRecord.fGoodRate=0;
m_Rand.SetTimerSeed();
for(m_fCurLAxis=m_fLAxisFrom;m_fCurLAxis<=80;m_fCurLAxis+=m_fLAxisAdd)
for(m_fCurSAxis=Max(m_fSAxisFrom,(float)sqrt(2*m_fCurLAxis*m_fObjRadius-m_fObjRadius*m_fObjRadius));m_fCurSAxis<m_fCurLAxis;m_fCurSAxis+=m_fSAxisAdd)
{
m_nGoodPhotonCount=0;
m_nBadPhotonCount=0;
m_nDeadPhotonCount=0;
m_fFocus=this->GetFocus(this->m_fCurLAxis);
for(int i=1;i<=this->m_nAllPhoton;i++)
{
IsDie=false;
if(m_nObjSort==0)//球面
{
//-----------产生随机光子并发射之--------------
pReflectLine.dPointDirct.dx=(float)m_Rand.DrawRandomNumber();
pReflectLine.dPointDirct.dy=(float)m_Rand.DrawRandomNumber();
pReflectLine.dPointDirct.dz=(float)m_Rand.DrawRandomNumber();
pReflectLine.pPassPoint.x=this->GetSAxis(this->m_fCurLAxis);
pReflectLine.pPassPoint.y=(float)m_Rand.DrawRandomNumber()/100*2*m_fCurSAxis*m_fCurSAxis/m_fCurLAxis-m_fCurSAxis*m_fCurSAxis/m_fCurLAxis;
pReflectLine.pPassPoint.z=(float)m_Rand.DrawRandomNumber()/100*2*m_fCurSAxis*m_fCurSAxis/m_fCurLAxis-m_fCurSAxis*m_fCurSAxis/m_fCurLAxis;
//---------------------------------------------
}
else
{
//-----------产生随机光子并发射之--------------
pReflectLine.dPointDirct.dx=(float)m_Rand.DrawRandomNumber();
pReflectLine.dPointDirct.dy=(float)m_Rand.DrawRandomNumber();
pReflectLine.dPointDirct.dz=(float)m_Rand.DrawRandomNumber();
pReflectLine.pPassPoint.x=(float)m_Rand.DrawRandomNumber()/100*2*this->m_fObjRadius+this->m_fFocus-this->m_fObjRadius;
pReflectLine.pPassPoint.y=(float)m_Rand.DrawRandomNumber()/100*2*this->m_fObjRadius-this->m_fObjRadius;
pReflectLine.pPassPoint.z=(float)m_Rand.DrawRandomNumber()/100*2*this->m_fObjRadius-this->m_fObjRadius;
//---------------------------------------------
}
//-----------------求出交点--------------------
pCutPoint=this->GetCutPoint(pReflectLine,-1);
//---------------------------------------------
pReflectLine.pPassPoint.x=pCutPoint.x;
pReflectLine.pPassPoint.y=pCutPoint.y;
pReflectLine.pPassPoint.z=pCutPoint.z;
//光子在没有被光电管接收或被物体消灭之前不停的在椭球内反射
for(nReflectCount=0;nReflectCount<=this->m_nReflectCount;nReflectCount++)
{
//得出反射直线,反射直线的方程:(x-x1)/x2=(y-y1)/y2=(z-z1)/z2
pReflectLine=this->GetReflectLine(pReflectLine);
pTempPoint=pCutPoint;
//求出反射直线与椭球的交点
pCutPoint=this->GetCutPoint(pReflectLine,1);
if(this->IsEven(pCutPoint,pTempPoint))
pCutPoint=this->GetCutPoint(pReflectLine,-1);
switch(this->IsCutWithPipe(pReflectLine))
{
case -1://不与光电管相交
break;
case 0://光子消灭
IsDie=true;
break;
case 1://光子被光电管接收
IsSorb=true;
m_nGoodPhotonCount+=1;
break;
default:
break;
}
//是否与物体相交
if(this->IsCutWithObj(pReflectLine,m_nObjSort))
IsDie=true;
if(IsDie)
m_nBadPhotonCount+=1;
if(IsDie || IsSorb)
break;
}
}
//--------------------------插入记录-----------------------------------
m_nDeadPhotonCount=m_nAllPhoton-m_nGoodPhotonCount-m_nBadPhotonCount;
m_fGoodRate=(float)this->m_nGoodPhotonCount/this->m_nAllPhoton;
m_fBadRate=(float)this->m_nBadPhotonCount/this->m_nAllPhoton;
m_fDeadRate=(float)this->m_nDeadPhotonCount/this->m_nAllPhoton;
m_Record.fLAxis=this->m_fCurLAxis;
m_Record.fSAxis=this->m_fCurSAxis;
m_Record.nBadPhotonCount=this->m_nBadPhotonCount;
m_Record.nGoodPhotonCount=this->m_nGoodPhotonCount;
m_Record.nDeadPhotonCount=this->m_nDeadPhotonCount;
m_Record.fGoodRate=this->m_fGoodRate;
m_Record.fBadRate=this->m_fBadRate;
m_Record.fDeadRate=this->m_fDeadRate;
m_pSimulatingView->InsertRecord(m_Record);
//---------------------------------------------------------------------
//--------------------------记录最佳效果-------------------------------
if(m_fGoodRate>m_MaxRecord.fGoodRate)
{
m_MaxRecord.fLAxis=this->m_fCurLAxis;
m_MaxRecord.fSAxis=this->m_fCurSAxis;
m_MaxRecord.nIndex=m_pCurView->m_pList->GetItemCount();
m_MaxRecord.nGoodPhotonCount=this->m_nGoodPhotonCount;
m_MaxRecord.fGoodRate=this->m_fGoodRate;
m_MaxRecord.fBadRate=this->m_fBadRate;
m_MaxRecord.fDeadRate=this->m_fDeadRate;
m_MaxRecord.nBadPhotonCount=this->m_nBadPhotonCount;
m_MaxRecord.nDeadPhotonCount=this->m_nDeadPhotonCount;
m_MaxRecord.nGoodPhotonCount=this->m_nGoodPhotonCount;
m_pSimulateViewList->rMaxRecord=m_MaxRecord;
}
//--------------------------------------------------------------------
}
return 0;
}
void CMainFrame::OnPause()
{
// TODO: Add your command handler code here
/* CMenu* pMenu = GetMenu();
CMenu* pSub = pMenu->GetSubMenu(0);
pSub->EnableMenuItem(IDM_STOP, MF_GRAYED);
pSub->EnableMenuItem(IDM_START, MF_ENABLED);
m_wndToolBar.SendMessage(TB_SETSTATE, IDM_STOP, MAKELONG(TBSTATE_INDETERMINATE,0));
m_wndToolBar.SendMessage(TB_SETSTATE, IDM_START, MAKELONG(TBSTATE_ENABLED,0));
*/
if(!m_bStop)
{
m_bStop = TRUE;
::TerminateThread(m_hThread, 0);
::WaitForSingleObject(m_hThread, INFINITE);
::CloseHandle(m_hThread);
m_wndStatusBar.SetPaneText(0,"暂停计算机模拟",true);
//改变设置对话框里面的设置
SetParam sp;
//---------------封装------------------------
sp.fLAxisAdd=m_fLAxisAdd;
sp.fLAxisFrom=this->m_fCurLAxis;
sp.fObjRadius=m_fObjRadius;
sp.fSAxisAdd=m_fSAxisAdd;
sp.fSAxisFrom=this->m_fCurSAxis;
sp.fShineIntensity=m_fShineIntensity;
sp.nAllPhoton=m_nAllPhoton;
sp.nReflectCount=m_nReflectCount;
sp.nObjSort=m_nObjSort;
//-------------------------------------------
m_dlgSet.ChangeSet(sp);
//状态栏进度条停止
m_wndStatusBar.StopRun();
m_wndStatusBar.SetViewProgress(false);
}
}
void CMainFrame::OnStop()
{
// TODO: Add your command handler code here
if(!m_bStop)
{
m_bStop = TRUE;
::TerminateThread(m_hThread, 0);
::WaitForSingleObject(m_hThread, INFINITE);
::CloseHandle(m_hThread);
if(!m_pMainFrame)
m_pMainFrame=(CMainFrame*)::AfxGetApp()->m_pMainWnd;
m_pMainFrame->m_wndStatusBar.SetPaneText(0,"停止计算机模拟",true);
//状态栏进度条停止
m_wndStatusBar.StopRun();
m_wndStatusBar.SetViewProgress(false);
}
// CMenu* pMenu = GetMenu();
// CMenu* pSub = pMenu->GetSubMenu(0);
// pSub->EnableMenuItem(IDM_STOP, MF_GRAYED);
// pSub->EnableMenuItem(IDM_START, MF_ENABLED);
// m_pMainFrame->m_wndToolBar.SendMessage(TB_SETSTATE, IDM_STOP, MAKELONG(TBSTATE_INDETERMINATE,0));
// m_pMainFrame->m_wndToolBar.SendMessage(TB_SETSTATE, IDM_START, MAKELONG(TBSTATE_ENABLED,0));
}
void CMainFrame::OnSet()
{
// TODO: Add your command handler code here
m_dlgSet.DoModal();
}
float CMainFrame::Min(float a, float b)
{
if(a<=b)
return a;
else
return b;
}
float CMainFrame::Max(float a, float b)
{
if(a>=b)
return a;
else
return b;
}
Point CMainFrame::GetCutPoint(Line l0,int nID)
{
Point pPoint;
float a,b,c;//椭球的长短半轴(50<=a<=80):椭圆方程:x*x/a^2+y*y/b^2+z*z/b^2=1
float px0,py0,pz0,dx0,dy0,dz0; //已知直线:(x-px0)/dx0=(y-py0)/dy0=(z-pz0)/dz0=k
float cx,cy,cz;//已知直线l与椭球的交点
a=this->m_fCurLAxis;
b=this->m_fCurSAxis;
c=this->m_fFocus;
px0=l0.pPassPoint.x;
py0=l0.pPassPoint.y;
pz0=l0.pPassPoint.z;
dx0=l0.dPointDirct.dx;
dy0=l0.dPointDirct.dy;
dz0=l0.dPointDirct.dz;
//椭球与已知直线联立方程得:(a2*a2/a^2+b2^2/b^2+c2^2/b^2)k1^2+2*(a2*a1/a^2+b2*b1/b^2+c2*c1/b^2)+(a1^2/a^2+b1^2/b^2+c1^2/b^2-1)=0
float m,n,p,k;
m=dx0*dx0/(a*a)+dy0*dy0/(b*b)+dz0*dz0/(b*b);
n=dx0*px0/(a*a)+dy0*py0/(b*b)+dz0*pz0/(b*b);
p=px0*px0/(a*a)+py0*py0/(b*b)+pz0*pz0/(b*b)-1;
if(nID==1)
k=(float)(-n+sqrt(n*n-m*p))/m;
else
if(nID==-1)
k=(float)(-n-sqrt(n*n-m*p))/m;
//求出交点
cx=dx0*k+px0;
cy=dy0*k+py0;
cz=dz0*k+pz0;
pPoint.x=cx;
pPoint.y=cy;
pPoint.z=cz;
return pPoint;
}
Line CMainFrame::GetReflectLine(Line l0)
{
float a,b,c;//椭球的长短半轴(50<=b<=80):椭圆方程:x*x/a^2+y*y/b^2+z*z/b^2=1
float cx0,cy0,cz0,dx0,dy0,dz0; //已知直线:(x-cx0)/dx0=(y-cy0)/dy0=(z-cz0)/dz0=k
float dx1,dy1,dz1;//对称轴:a*a*(x-cx0)/cx0=b*b*(y-cy0)/cy0=b*b*(z-cz0)/cz0
Line lRet; //返回的直线
a=this->m_fCurLAxis;
b=this->m_fCurSAxis;
c=this->m_fFocus;
cx0=l0.pPassPoint.x;
cy0=l0.pPassPoint.y;
cz0=l0.pPassPoint.z;
dx0=l0.dPointDirct.dx;
dy0=l0.dPointDirct.dy;
dz0=l0.dPointDirct.dz;
dx1=cx0/(a*a);
dy1=cy0/(b*b);
dz1=cz0/(b*b);
float k;
k=2*(dx1*dx0+dy1*dy0+dz1*dz0)/(dx1*dx1+dy1*dy1+dz1*dz1);
lRet.dPointDirct.dx=dx1*k-dx0;
lRet.dPointDirct.dy=dy1*k-dy0;
lRet.dPointDirct.dz=dz1*k-dz0;
lRet.pPassPoint.x=cx0;
lRet.pPassPoint.y=cy0;
lRet.pPassPoint.z=cz0;
return lRet;
}
float CMainFrame::GetSAxis(float fLAxis)
{
return (float)sqrt(1.41*this->m_fCurLAxis);
}
float CMainFrame::GetFocus(float fLAxis)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -