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

📄 femmedoc.cpp

📁 一个2D电磁场FEM计算的VC++源程序
💻 CPP
📖 第 1 页 / 共 5 页
字号:

            if (d<dmin){
				
				CComplex a0,a1,a2;
				a0.Set(nodelist[asegm.n0].x,nodelist[asegm.n0].y);
				a1.Set(nodelist[asegm.n1].x,nodelist[asegm.n1].y);
				a2.Set(nodelist[i].x,nodelist[i].y);
                arclist[k].ToggleSelect();
                DeleteSelectedArcSegments();

				newarc=asegm;
				newarc.n1=i;
				newarc.ArcLength=arg((a2-c)/(a0-c))*180./PI;
                AddArcSegment(newarc,dmin);

				newarc=asegm;
				newarc.n0=i;
				newarc.ArcLength=arg((a1-c)/(a2-c))*180./PI;
                AddArcSegment(newarc,dmin);

                i=nodelist.GetSize();
            }
        }
    }

	return TRUE;
}


BOOL CFemmeDoc::AddBlockLabel(double x, double y, double d)
{
	int i;
	BOOL AddFlag=TRUE;

	// test to see if ``too close'' to existing node...
	for (i=0;i<blocklist.GetSize();i++)
		if(blocklist[i].GetDistance(x,y)<d) AddFlag=FALSE;

	// can't put a block label on top of an existing node...
	for (i=0;i<nodelist.GetSize();i++)
		if(nodelist[i].GetDistance(x,y)<d) return FALSE;

	// can't put a block label on a line, either...
	for (i=0;i<linelist.GetSize();i++)
		if(ShortestDistance(x,y,i)<d) return FALSE ;

	// if all is OK, add point in to the node list...
	if(AddFlag==TRUE){
		CBlockLabel pt;
		pt.x=x; pt.y=y;
		blocklist.Add(pt);
	}
	
	return TRUE;
}

int CFemmeDoc::ClosestNode(double x, double y)
{
	int i,j;
	double d0,d1;

	if(nodelist.GetSize()==0) return -1;

	j=0;
	d0=nodelist[0].GetDistance(x,y);
	for(i=0;i<nodelist.GetSize();i++){
		d1=nodelist[i].GetDistance(x,y);
		if(d1<d0){
			d0=d1;
			j=i;
		}
	}

	return j;
}

int CFemmeDoc::ClosestBlockLabel(double x, double y)
{
	int i,j;
	double d0,d1;

	if(blocklist.GetSize()==0) return -1;

	j=0;
	d0=blocklist[0].GetDistance(x,y);
	for(i=0;i<blocklist.GetSize();i++){
		d1=blocklist[i].GetDistance(x,y);
		if(d1<d0){
			d0=d1;
			j=i;
		}
	}

	return j;
}

double CFemmeDoc::ShortestDistanceFromArc(CComplex p, CArcSegment &arc)
{
	double R,d,l,z;
	CComplex a0,a1,c,t;

	a0.Set(nodelist[arc.n0].x,nodelist[arc.n0].y);
	a1.Set(nodelist[arc.n1].x,nodelist[arc.n1].y);
	GetCircle(arc,c,R);
	d=abs(p-c);
	
	if(d==0) return R;
	
	t=(p-c)/d;
	l=abs(p-c-R*t);
	z=arg(t/(a0-c))*180/PI;
	if ((z>0) && (z<arc.ArcLength)) return l;
	
	z=abs(p-a0);
	l=abs(p-a1);
	if(z<l) return z;
	return l;
}
	

double CFemmeDoc::ShortestDistance(double p, double q, int segm)
{
	double t,x[3],y[3];
	
	x[0]=nodelist[linelist[segm].n0].x;
	y[0]=nodelist[linelist[segm].n0].y;
	x[1]=nodelist[linelist[segm].n1].x;
	y[1]=nodelist[linelist[segm].n1].y;

	t=((p-x[0])*(x[1]-x[0]) + (q-y[0])*(y[1]-y[0]))/
	  ((x[1]-x[0])*(x[1]-x[0]) + (y[1]-y[0])*(y[1]-y[0]));

	if (t>1.) t=1.;
	if (t<0.) t=0.;

	x[2]=x[0]+t*(x[1]-x[0]);
	y[2]=y[0]+t*(y[1]-y[0]);

	return sqrt((p-x[2])*(p-x[2]) + (q-y[2])*(q-y[2]));
}

int CFemmeDoc::ClosestSegment(double x, double y)
{
	double d0,d1;
	int i,j;

	if(linelist.GetSize()==0) return -1;

	j=0;
	d0=ShortestDistance(x,y,0);
	for(i=0;i<linelist.GetSize();i++){
		d1=ShortestDistance(x,y,i);
		if(d1<d0){
			d0=d1;
			j=i;
		}
	}

	return j;
}

int CFemmeDoc::ClosestArcSegment(double x, double y)
{
	double d0,d1;
	int i,j;

	if(arclist.GetSize()==0) return -1;

	j=0;
	d0=ShortestDistanceFromArc(CComplex(x,y),arclist[0]);
	for(i=0;i<arclist.GetSize();i++){
		d1=ShortestDistanceFromArc(CComplex(x,y),arclist[i]);
		if(d1<d0){
			d0=d1;
			j=i;
		}
	}

	return j;
}

BOOL CFemmeDoc::GetIntersection(int n0, int n1, int segm, double *xi, double *yi)
// prospective line specified by n0,n1;
// segment specified by segm;
// coordinates of the intersection returned in xi,yi
{
	double t[2],x[2],y[2],p[2],q[2],det;
	double SmallNum=1.e-08;
	BOOL z;
	
	// Get a definition of "real small" based on the lengths
	// of the lines of interest;
	SmallNum=min(abs(nodelist[linelist[segm].n0].CC()-nodelist[linelist[segm].n1].CC()),
				 abs(nodelist[n0].CC()-nodelist[n1].CC()));
	SmallNum*=1.e-8;

	x[0]=nodelist[linelist[segm].n0].x;
	y[0]=nodelist[linelist[segm].n0].y;
	x[1]=nodelist[linelist[segm].n1].x;
	y[1]=nodelist[linelist[segm].n1].y;


	p[0]=nodelist[n0].x;
	q[0]=nodelist[n0].y;
	p[1]=nodelist[n1].x;
	q[1]=nodelist[n1].y;

	det=(p[1]-p[0])*(y[1]-y[0]) - (q[1]-q[0])*(x[1]-x[0]);

	if (sqrt(fabs(det))<SmallNum) return FALSE;		// lines are parallel

	t[0]=((p[1]-p[0])*(q[0]-y[0]) - (q[1]-q[0])*(p[0]-x[0]))/det;
	t[1]=((x[1]-x[0])*(q[0]-y[0]) - (y[1]-y[0])*(p[0]-x[0]))/det;
	
	
	// check to see if the line segments intersect at a point sufficiently
	// far from the segment endpoints....
	z=TRUE;
	if(t[0]<SmallNum)	z=FALSE;
	if(t[1]<SmallNum)	z=FALSE;
	if(t[0]>1.-SmallNum) z=FALSE;
	if(t[1]>1.-SmallNum) z=FALSE;
	
	*xi=x[0]+t[0]*(x[1]-x[0]);
	*yi=y[0]+t[0]*(y[1]-y[0]);

//	if (z) AfxMessageBox("Intersection");
//	else AfxMessageBox("No Intersection");

	return z;
}

BOOL CFemmeDoc::DeleteSelectedBlockLabels()
{
	int i=0;
	BOOL flag=FALSE;

	if (blocklist.GetSize() > 0) do{
		if(blocklist[i].IsSelected==TRUE){
			blocklist.RemoveAt(i,1);
			flag=TRUE;
		}
		else i++;
	} while (i<blocklist.GetSize());
	
	blocklist.FreeExtra();
	return flag;
}

BOOL CFemmeDoc::DeleteSelectedSegments()
{
	int i=0;
	BOOL flag=FALSE;

	if (linelist.GetSize() > 0)	do{
		if(linelist[i].IsSelected==TRUE){
			linelist.RemoveAt(i,1);
			flag=TRUE;
		}
		else i++;
	} while (i<linelist.GetSize());

	linelist.FreeExtra();

	return flag;
}

BOOL CFemmeDoc::DeleteSelectedArcSegments()
{
	int i=0;
	BOOL flag=FALSE;

	if (arclist.GetSize() > 0)	do{
		if(arclist[i].IsSelected==TRUE){
			arclist.RemoveAt(i,1);
			flag=TRUE;
		}
		else i++;
	} while (i<arclist.GetSize());

	arclist.FreeExtra();

	return flag;
}

BOOL CFemmeDoc::DeleteSelectedNodes()
{
	int i=0;
	int j;
	BOOL flag=FALSE;

	if (nodelist.GetSize() > 0) do{
		if(nodelist[i].IsSelected==TRUE){
			flag=TRUE;
			// first remove all lines that contain the point;
			for(j=0;j<linelist.GetSize();j++)
				if((linelist[j].n0==i) || (linelist[j].n1==i)) 
					linelist[j].ToggleSelect();
			DeleteSelectedSegments(); 
			
			// remove all arcs that contain the point;
			for(j=0;j<arclist.GetSize();j++)
				if((arclist[j].n0==i) || (arclist[j].n1==i)) 
					arclist[j].ToggleSelect();
			DeleteSelectedArcSegments(); 

			// remove node from the nodelist...
			nodelist.RemoveAt(i,1);

			// update lines to point to the new node numbering
			for(j=0;j<linelist.GetSize();j++){
				if (linelist[j].n0>i) linelist[j].n0--;
				if (linelist[j].n1>i) linelist[j].n1--;
			}

			// update arcs to point to the new node numbering
			for(j=0;j<arclist.GetSize();j++){
				if (arclist[j].n0>i) arclist[j].n0--;
				if (arclist[j].n1>i) arclist[j].n1--;
			}
		}
		else i++;
	} while (i<nodelist.GetSize());

	nodelist.FreeExtra();

	return flag;
}

void CFemmeDoc::OnEditMatprops() 
{
	// TODO: Add your command handler code here
	CPtProp pProp;

	pProp.pblockproplist=&blockproplist;
	pProp.PropType=2;
	pProp.ProblemType=ProblemType;

	pProp.DoModal();
}

void CFemmeDoc::OnEditPtprops() 
{
	// TODO: Add your command handler code here
	CPtProp pProp;
	
	pProp.pnodeproplist=&nodeproplist;
	pProp.PropType=0;

	pProp.DoModal();
}

void CFemmeDoc::OnEditSegprops() 
{
	// TODO: Add your command handler code here
	CPtProp pProp;

	pProp.plineproplist=&lineproplist;
	pProp.PropType=1;
	pProp.ProblemType=ProblemType;
	pProp.DoModal();
}

void CFemmeDoc::OnEditCircprops() 
{
	CPtProp pProp;
	
	pProp.pcircproplist=&circproplist;
	pProp.ProblemType=ProblemType;
	pProp.PropType=3;

	pProp.DoModal();
}

BOOL CFemmeDoc::OpBlkDlg()
{
	int i,j,k,nselected,cselected;
	double a;
	COpBlkDlg zDlg;	

	zDlg.ProblemType=ProblemType;

	// check to see how many (if any) blocks are selected.
	for(i=0,k=0,nselected=0,cselected=0;i<blocklist.GetSize();i++)
	{
		if (blocklist[i].IsSelected==TRUE){
			if(nselected==0){
				nselected++;
				zDlg.m_ingroup=blocklist[i].InGroup;
			}
			else if(blocklist[i].BlockType!=blocklist[k].BlockType)
				nselected++;
			if(cselected==0) cselected++;
			else if(blocklist[i].InCircuit!=blocklist[k].InCircuit)
				cselected++;
			if(blocklist[i].InGroup!=zDlg.m_ingroup) zDlg.m_ingroup=0;
			k=i;
			if(blocklist[i].IsExternal) zDlg.m_isexternal=TRUE;
		}
	}
	if (nselected==0) return FALSE;
	
	// find average block size;
	for(i=0,j=0,a=0.;i<blocklist.GetSize();i++)
		if(blocklist[i].IsSelected==TRUE)
			if (blocklist[i].MaxArea>a) a=blocklist[i].MaxArea;

	zDlg.m_sidelength=floor(2.e07*sqrt(a/PI)+0.5)/1.e07;

	zDlg.pblockproplist=&blockproplist;
	zDlg.pcircproplist=&circproplist;
	
	if (nselected==1){
		if(blocklist[k].BlockType=="<No Mesh>") zDlg.cursel=1;
		else for(i=0,zDlg.cursel=0;i<blockproplist.GetSize();i++)
			if (blockproplist[i].BlockName==blocklist[k].BlockType)
				zDlg.cursel=i+2;
	}
	else zDlg.cursel=0;

	if (cselected==1){
		for(i=0,zDlg.circsel=0;i<circproplist.GetSize();i++)
			if (circproplist[i].CircName==blocklist[k].InCircuit)
				zDlg.circsel=i+1;
	}
	else zDlg.circsel=0;

	zDlg.m_magdir=blocklist[k].MagDir;
	zDlg.m_turns=blocklist[k].Turns;

	if (zDlg.DoModal()==IDOK){
		for(i=0;i<blocklist.GetSize();i++)
		{
			if(blocklist[i].IsSelected==TRUE){
				blocklist[i].MaxArea=PI*zDlg.m_sidelength*zDlg.m_sidelength/4.;
				blocklist[i].MagDir=zDlg.m_magdir;
				blocklist[i].Turns=zDlg.m_turns;
				if (blocklist[i].Turns==0) blocklist[i].Turns++;
				if (zDlg.cursel==0) blocklist[i].BlockType="<None>";
				else if(zDlg.cursel==1) blocklist[i].BlockType="<No Mesh>";
				else blocklist[i].BlockType=blockproplist[zDlg.cursel-2].BlockName;
				if (zDlg.circsel==0) blocklist[i].InCircuit="<None>";
				else blocklist[i].InCircuit=circproplist[zDlg.circsel-1].CircName;
				blocklist[i].InGroup=zDlg.m_ingroup;
				blocklist[i].IsExternal=zDlg.m_isexternal;
			}
		}
		return TRUE;
	}

	return FALSE;
}

void CFemmeDoc::OpNodeDlg()
{
	int i,k,nselected;
	COpNodeDlg zDlg;	

	// check to see how many (if any) nodes are selected.
	for(i=0,k=0,nselected=0;i<nodelist.GetSize();i++)
	{
		if (nodelist[i].IsSelected==TRUE){
			if(nselected==0){
				nselected++;
				zDlg.m_ingroup=nodelist[i].InGroup;
			}
			else if(nodelist[i].BoundaryMarker!=nodelist[k].BoundaryMarker)
				nselected++;
			if(nodelist[i].InGroup!=zDlg.m_ingroup) zDlg.m_ingroup=0;
			k=i;
		}
	}
	if (nselected==0) return;

	zDlg.pnodeproplist=&nodeproplist;
	if (nselected==1){
		for(i=0,zDlg.cursel=0;i<nodeproplist.GetSize();i++)
			if (nodeproplist[i].PointName==nodelist[k].BoundaryMarker)
				zDlg.cursel=i+1;
	}
	else zDlg.cursel=0;

	if (zDlg.DoModal()==IDOK){
		for(i=0;i<nodelist.GetSize();i++)
		{
			if(nodelist[i].IsSelected==TRUE){
				if (zDlg.cursel==0) nodelist[i].BoundaryMarker="<None>";
				else nodelist[i].BoundaryMarker=nodeproplist[zDlg.cursel-1].PointName;
				nodelist[i].InGroup=zDlg.m_ingroup;
			}
		}
	}
}
 
void CFemmeDoc::OpSegDlg()
{
	int i,j,k,nselected;
	COpSegDlg zDlg;	

	// check to see how many (if any) nodes are selected.
	for(i=0,k=0,nselected=0;i<linelist.GetSize();i++)
	{
		if (linelist[i].IsSelected==TRUE){
			if(nselected==0){
				nselected++;
				zDlg.m_ingroup=linelist[i].InGroup;
			}
			else if(linelist[i].BoundaryMarker!=linelist[k].BoundaryMarker)
				nselected++;
			if(linelist[i].InGroup!=zDlg.m_ingroup) zDlg.m_ingroup=0;
			k=i;
		}
	}
	if (nselected==0) return;

	// find properties block size;
	double ms=0;
	zDlg.m_hide=FALSE;
	for(i=0,j=0;i<linelist.GetSize();i++)
		if(linelist[i].IsSelected==TRUE){
			if(linelist[i].MaxSideLength<0) ms=-1;
			if (ms>=0) ms+=linelist[k].MaxSideLength;
			j++;
			if (linelist[i].Hidden==TRUE) zDlg.m_hide=TRUE;
		}
	ms/=(double) j;

	zDlg.plineproplist=&lineproplist;
	if (nselected==1){
		for(i=0,zDlg.cursel=0;i<lineproplist.GetSize();i++)
			if (lineproplist[i].BdryName==linelist[k].BoundaryMarker)
				zDlg.cursel=i+1;
	}
	else zDlg.cursel=0;

	if (ms<0){
		zDlg.m_automesh=TRUE;
		zDlg.m_linemeshsize=0;
	}
	else{
		zDlg.m_automesh=FALSE;
		zDlg.m_linemeshsize=ms;
	}

	if (zDlg.DoModal()==IDOK){
		for(i=0;i<linelist.GetSize();i++)
		{
			if(linelist[i].IsSelected==TRUE){
			
				if (zDlg.m_automesh==TRUE) linelist[i].MaxSideLength=-1;
				else{

⌨️ 快捷键说明

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