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

📄 mainfrm.cpp

📁 运用扫描法求设计一个最佳比例的聚光腔
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	}

	//状态栏进度条启动
//	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 + -