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

📄 csdareamethod.cpp

📁 能在MDT5/6环境下对已经存在地曲面进行全部和局部区域展开
💻 CPP
📖 第 1 页 / 共 5 页
字号:
#include "stdafx.h"
#include "StdArx.h"

#include "CSDAreaMethod.h"
#include "GeUtilities.h"
#include "CreateDbObj.h"

#include "DbUtilities.h"

#include <MATH.H>		// sqrt

#ifndef PI
#define PI	3.1415926535897932384626433832795
#endif


// 空间四边形展开,已知展开四边形的三点求第四点
// pntArr1是空间四边形顶点数组分别为左下,右下,左上,右上,4个成员
// pntArr2是展开后平面四边形顶点数组分别为左下,右下,左上,右上,4个成员,其中右上为返回值
void quadrangle4thPoint(const AcGePoint3dArray& pntArr1,AcGePoint2dArray& pntArr2);


// 已知展开中心以及周围四点,求展开平面上相应四点
// pntArr1是空间顶点数组,分别为中心,右,上,左,下,5个成员
// pntArr2是平面顶点数组,分别为中心,右,上,左,下,5个成员,其中后四个为返回值
void centerArounded4Points(const AcGePoint3dArray& pntArr1,AcGePoint2dArray& pntArr2);


// 空间四边形展开,已知展开四边形的两点求第三点
// pntArr1是空间四边形顶点数组分别为左下,右下,左上,右上,4个成员,右上未用
// pntArr2是展开后平面四边形顶点数组分别为左下,右下,左上,右上,4个成员,
// 其中左下和左上为已知,右下为返回值,右上未用
void quadrangle3rdPoint(const AcGePoint3dArray& pntArr1,AcGePoint2dArray& pntArr2);



void quadrangle4thPoint(const AcGePoint3dArray& pntArr1,AcGePoint2dArray& pntArr2)
{
	if (pntArr1.length()<4) 
		return;
	if (pntArr1.at(3).isEqualTo(pntArr1.at(2))) {
		// 当所求的右上与右下相同时,也同样赋值
		pntArr2[3] = pntArr2[2];
	}
	if (pntArr1.at(3).isEqualTo(pntArr1.at(1))) {
		// 当所求的右上与左上相同时,也同样赋值
		pntArr2[3] = pntArr2[1];
	}

	double sigma[3],A,B,C,D,E;
	
	sigma[0] = triangleArea(pntArr1[2],pntArr1[1],pntArr1[3]);
	sigma[1] = triangleArea(pntArr1[2],pntArr1[0],pntArr1[3]);
	sigma[2] = triangleArea(pntArr1[0],pntArr1[1],pntArr1[3]);

	A = (pntArr2[2].x-pntArr2[1].x)*(pntArr2[2].y-pntArr2[1].y)
		+ (pntArr2[2].x-pntArr2[0].x)*(pntArr2[2].y-pntArr2[0].y)
		+ (pntArr2[0].x-pntArr2[1].x)*(pntArr2[0].y-pntArr2[1].y);
	B = (pntArr2[2].x-pntArr2[1].x)*(pntArr2[2].x-pntArr2[1].x)
		+ (pntArr2[2].x-pntArr2[0].x)*(pntArr2[2].x-pntArr2[0].x)
		+ (pntArr2[0].x-pntArr2[1].x)*(pntArr2[0].x-pntArr2[1].x);
	C = (pntArr2[2].x*pntArr2[1].y-pntArr2[1].x*pntArr2[2].y-2*sigma[0])*(pntArr2[2].x-pntArr2[1].x)
		+ (pntArr2[2].x*pntArr2[0].y-pntArr2[0].x*pntArr2[2].y-2*sigma[1])*(pntArr2[2].x-pntArr2[0].x)
		+ (pntArr2[0].x*pntArr2[1].y-pntArr2[1].x*pntArr2[0].y-2*sigma[2])*(pntArr2[0].x-pntArr2[1].x);
	D = (pntArr2[2].y-pntArr2[1].y)*(pntArr2[2].y-pntArr2[1].y)
		+ (pntArr2[2].y-pntArr2[0].y)*(pntArr2[2].y-pntArr2[0].y)
		+ (pntArr2[0].y-pntArr2[1].y)*(pntArr2[0].y-pntArr2[1].y);
	E = (pntArr2[2].x*pntArr2[1].y-pntArr2[1].x*pntArr2[2].y-2*sigma[0])*(pntArr2[2].y-pntArr2[1].y)
		+ (pntArr2[2].x*pntArr2[0].y-pntArr2[0].x*pntArr2[2].y-2*sigma[1])*(pntArr2[2].y-pntArr2[0].y)
		+ (pntArr2[0].x*pntArr2[1].y-pntArr2[1].x*pntArr2[0].y-2*sigma[2])*(pntArr2[0].y-pntArr2[1].y);

	pntArr2[3].x = (C*A-B*E)/(B*D-A*A);
	pntArr2[3].y = (C*D-A*E)/(B*D-A*A);

	double area;
	Adesk::Boolean bRight;

	bRight = isClockwise(pntArr2[3],pntArr2[1],pntArr2[2]);
	if (bRight) {
		area = triangleArea(pntArr2[2],pntArr2[1],pntArr2[3]);
		area = fabs(area);
		sigma[0] = fabs(sigma[0]);
	}

	if (!bRight || area/sigma[0]>1.2 || sigma[0]/area>1.2) {
		// 单独用上述公式计算得出的结果有时不好用,
		// 对于一头大一头小的曲面不合用,会出现突变, 数值可调
		AcGePoint3dArray tpnts1;
		AcGePoint2dArray tpnts2;
		tpnts1.setLogicalLength(4);
		tpnts2.setLogicalLength(4);
		tpnts1[0] = pntArr1[1];
		tpnts1[1] = pntArr1[3];
		tpnts1[2] = pntArr1[2];
		tpnts2[0] = pntArr2[1];
		tpnts2[2] = pntArr2[2];
		quadrangle3rdPoint(tpnts1,tpnts2);
		pntArr2[3] = tpnts2[1];
	}	
}

void centerArounded4Points(const AcGePoint3dArray& pntArr1,AcGePoint2dArray& pntArr2)
{
	double beita[4],b[4],gama,alpha,l[4],t;
	double temp;
	AcGeVector3d vec1,vec2;
	AcGeVector2d vec2d;
	
	vec1 = pntArr1[0]-pntArr1[1];
	vec2 = pntArr1[0]-pntArr1[2];
	l[1] = vec2.length();
	beita[0] = vec1.angleTo(vec2);	

	vec1 = pntArr1[0]-pntArr1[3];
	l[2] = vec1.length();
	beita[1] = vec2.angleTo(vec1);	

	vec2 = pntArr1[0]-pntArr1[4];
	l[3] = vec2.length();
	beita[2] = vec1.angleTo(vec2);	

	vec1 = pntArr1[0]-pntArr1[1];
	l[0] = vec1.length();
	beita[3] = vec2.angleTo(vec1);	

	alpha = beita[0]+beita[1]+beita[2]+beita[3];
	gama = 2*PI - alpha;
	
	b[0] = beita[0]+beita[0]/alpha*gama;
	b[1] = beita[1]+beita[1]/alpha*gama;
	b[2] = beita[2]+beita[2]/alpha*gama;
	b[3] = beita[3]+beita[3]/alpha*gama;

	t = l[0]*l[1]*sin(beita[0]) + l[1]*l[2]*sin(beita[1]) + l[2]*l[3]*sin(beita[2]) + l[3]*l[0]*sin(beita[3]);
	temp = l[0]*l[1]*sin(b[0]) + l[1]*l[2]*sin(b[1]) + l[2]*l[3]*sin(b[2]) + l[3]*l[0]*sin(b[3]);
	t = sqrt(t/temp);

	temp = 0.0f;	pntArr2[1] = pntArr2[0] + AcGeVector2d(l[0]*t*cos(temp),l[0]*t*sin(temp));
	temp += b[0];	pntArr2[2] = pntArr2[0] + AcGeVector2d(l[1]*t*cos(temp),l[1]*t*sin(temp));
	temp += b[1];	pntArr2[3] = pntArr2[0] + AcGeVector2d(l[2]*t*cos(temp),l[2]*t*sin(temp));
	temp += b[2];	pntArr2[4] = pntArr2[0] + AcGeVector2d(l[3]*t*cos(temp),l[3]*t*sin(temp));
}


void quadrangle3rdPoint(const AcGePoint3dArray& pntArr1,AcGePoint2dArray& pntArr2)
{
	if (pntArr1.length()<4) 
		return;
	if (pntArr1[0].isEqualTo(pntArr1[1])) {
		pntArr2[1] = pntArr2[0];
		return;
	}
	if (pntArr1[2].isEqualTo(pntArr1[1])) {
		pntArr2[1] = pntArr2[2];
		return;
	}

	double sigma,d,l[3];
	AcGeLine2d baseLine,offLine;

	sigma = triangleArea(pntArr1[0],pntArr1[1],pntArr1[2]);
	l[0] = pntArr1[2].distanceTo(pntArr1[0]);
	d = 2*sigma/l[0];

	baseLine.set(pntArr2[2],pntArr2[0]);
	AcGeOffsetCurve2d offCrv(baseLine,d);
	offCrv.isLinear(offLine);

	l[1] = pntArr1[2].distanceTo(pntArr1[1]);
	l[2] = pntArr1[0].distanceTo(pntArr1[1]);

	int intnp, intnq;
	AcGePoint2d p1,p2,pu,q1,q2,qv;
	AcGeCircArc2d c1(pntArr2[2],l[1],0.0f,2.0*PI);
	AcGeCircArc2d c2(pntArr2[0],l[2],0.0f,2.0*PI);

	c1.intersectWith(offLine,intnp,p1,p2);
	if(intnp<2) {
		c1.intersectWith(c2,intnp,p1,p2);
		if(isClockwise(baseLine,p1)) {
			pntArr2[1] = p2;
		} else {
			pntArr2[1] = p1;
		}
		return;
	} else {
		c2.intersectWith(offLine,intnq,q1,q2);
		
		AcGeDoubleArray distArr;
		distArr.setLogicalLength(4);
		
		distArr[0] = p1.distanceTo(q1);
		distArr[1] = p1.distanceTo(q2);
		distArr[2] = p2.distanceTo(q1);
		distArr[3] = p2.distanceTo(q2);
		
		switch(minArr(distArr)) {
		case 0:
			pu = p1;	qv = q1;	break;
		case 1:
			pu = p1;	qv = q2;	break;
		case 2:
			pu = p2;	qv = q1;	break;
		case 3:
			pu = p2;	qv = q2;
		}
		pntArr2[1] = (pu+qv.asVector())/2;
	}
	
}

// dists[0]: 中心点处v线上距离中心点u负方向的距离
// dists[1]: 中心点处v线上距离中心点u正方向的距离
// dists[2]: 中心点处u线上距离中心点v负方向的距离
// dists[3]: 中心点处u线上距离中心点v正方向的距离
bool getEvalSection(CSDData& data,const AcGeDoubleArray& dists)
{
	if (dists.length()!=4 )	return false;

	double uln,vln,ulp,vlp;
	AcGePoint2d cparam,param;
	AcGeInterval intX,intY;
	uln = dists[0];		ulp = dists[1];
	vln = dists[2];		vlp = dists[3];
	data.oBaseSurf.isOn(data.oBaseSurf.closestPointTo(data.oCenter),cparam);
//	cparam = data.oBaseSurf.paramOf(data.oBaseSurf.closestPointTo(data.oCenter));
	data.oBaseSurf.getEnvelope(intX,intY);

	int i;
	double stepu,stepv,start;
	AcGePoint3d tmpC;
	double centerparam,tmp;
	AcGeNurbCurve3d uc,vc;
	AcGeInterval intrvl;

	int nU,nV;
	nU = data.nU;
	nV = data.nV;

	stepu = intX.length()/nU;
	stepv = intY.length()/nV;

	AcGePoint3dArray pntArr1;

	// u线
	start = intY.lowerBound();
	pntArr1.setLogicalLength(nV+1);
	for(i=0;i<nV+1;i++) {
		param.set(cparam.x,start);
		pntArr1[i] = data.oBaseSurf.evalPoint(param);
		start = start+stepv;
	}
	uc = AcGeNurbCurve3d(pntArr1);

	tmpC = uc.closestPointTo(data.oCenter);
	uc.isOn(tmpC,centerparam);
//	centerparam = uc.paramOf(tmpC);
	uc.getInterval(intrvl);

	// 设置v参数展开计算值范围
	double tol = AcGeContext::gTol.equalPoint();

	tmp = uc.paramAtLength(centerparam,vln,Adesk::kFalse);
	if (tmp<intrvl.lowerBound()) 
		tmp = intrvl.lowerBound();
	AcGePoint2d tParam2d;
	data.oBaseSurf.isOn(uc.evalPoint(tmp),tParam2d);
	tmp = tParam2d.y;
//	tmp = data.oBaseSurf.paramOf(uc.evalPoint(tmp)).y;
	data.oEvalV.setLower(tmp);

	tmp = uc.paramAtLength(centerparam,vlp,Adesk::kTrue);
	if (tmp==0) 
		tmp = intrvl.upperBound();
	data.oBaseSurf.isOn(uc.evalPoint(tmp),tParam2d);
	tmp = tParam2d.y;
//	tmp = data.oBaseSurf.paramOf(uc.evalPoint(tmp)).y;
	data.oEvalV.setUpper(tmp);


	// v线
	start = intX.lowerBound();
	pntArr1.setLogicalLength(nU+1);
	for(i=0;i<nU+1;i++) {
		param.set(start,cparam.y);
		pntArr1[i] = data.oBaseSurf.evalPoint(param);
		start = start+stepu;
	}
	vc = AcGeNurbCurve3d(pntArr1);
	
	tmpC = vc.closestPointTo(data.oCenter);
	vc.isOn(tmpC,centerparam);
//	centerparam = vc.paramOf(tmpC);
	vc.getInterval(intrvl);

	// 设置u参数展开计算值范围
	tmp = vc.paramAtLength(centerparam,uln,Adesk::kFalse);
	if (tmp<intrvl.lowerBound()) 
		tmp = intrvl.lowerBound();
	data.oBaseSurf.isOn(vc.evalPoint(tmp),tParam2d);
	tmp = tParam2d.x;
//	tmp = data.oBaseSurf.paramOf(vc.evalPoint(tmp)).x;
	data.oEvalU.setLower(tmp);

	tmp = vc.paramAtLength(centerparam,ulp,Adesk::kTrue);
	if (tmp==0) 
		tmp = intrvl.upperBound();
	data.oBaseSurf.isOn(vc.evalPoint(tmp),tParam2d);
	tmp = tParam2d.x;
//	tmp = data.oBaseSurf.paramOf(vc.evalPoint(tmp)).x;
	data.oEvalU.setUpper(tmp);

	AcGeNurbCurve3d uvAv; // uv平分线
	double dist;		  // 计算距离
	int len;

	// u线和v线角中分线, 左下中
	nU = int ((cparam.x-intX.lowerBound())/stepu);
	nV = int ((cparam.y-intY.lowerBound())/stepv);
	len = nU>nV ? nV:nU;
	if (len) {
		pntArr1.setLogicalLength(0);
		for (i=0; i<len+1; i++) {
			param.set(cparam.x-i*stepu,cparam.y-i*stepv);
			pntArr1.append(data.oBaseSurf.evalPoint(param));
		}
		uvAv = AcGeNurbCurve3d(pntArr1);
		
		tmpC = uvAv.closestPointTo(data.oCenter);
		uvAv.isOn(tmpC,centerparam);
		//	centerparam = vc.paramOf(tmpC);
		uvAv.getInterval(intrvl);

		dist = uln*uln + vln*vln;
		dist = sqrt(dist);
		// 设置u参数展开计算值范围
		tmp = uvAv.paramAtLength(centerparam,dist,Adesk::kTrue);
		if (tmp==0) 
			tmp = intrvl.upperBound();
		data.oBaseSurf.isOn(uvAv.evalPoint(tmp),tParam2d);
		if (data.oEvalU.lowerBound() > tParam2d.x) {
			data.oEvalU.setLower(tParam2d.x);
		}
		if (data.oEvalV.lowerBound() > tParam2d.y) {
			data.oEvalV.setLower(tParam2d.y);
		}
	}
/*
	// u线和v线角中分线, 左下下
	nU = int ((cparam.x-intX.lowerBound())/stepu);
	nV = int ((cparam.y-intY.lowerBound())/(stepv*2));
	len = nU>nV ? nV:nU;
	if (len) {
		pntArr1.setLogicalLength(0);
		for (i=0; i<len+1; i++) {
			param.set(cparam.x-i*stepu,cparam.y-i*stepv*2);
			pntArr1.append(data.oBaseSurf.evalPoint(param));
		}
		uvAv = AcGeNurbCurve3d(pntArr1);
		
		tmpC = uvAv.closestPointTo(data.oCenter);
		uvAv.isOn(tmpC,centerparam);
		//	centerparam = vc.paramOf(tmpC);
		uvAv.getInterval(intrvl);
		
		dist = uln*uln + vln*vln;
		dist = sqrt(dist);
		// 设置u参数展开计算值范围
		tmp = uvAv.paramAtLength(centerparam,dist,Adesk::kTrue);
		if (tmp==0) 
			tmp = intrvl.upperBound();
		data.oBaseSurf.isOn(uvAv.evalPoint(tmp),tParam2d);
		if (data.oEvalU.lowerBound() > tParam2d.x) {
			data.oEvalU.setLower(tParam2d.x);
		}
		if (data.oEvalV.lowerBound() > tParam2d.y) {
			data.oEvalV.setLower(tParam2d.y);
		}
	}
	// u线和v线角中分线, 左下上
	nU = int ((cparam.x-intX.lowerBound())/(stepu*2));
	nV = int ((cparam.y-intY.lowerBound())/stepv);
	len = nU>nV ? nV:nU;
	if (len) {
		pntArr1.setLogicalLength(0);
		for (i=0; i<len+1; i++) {
			param.set(cparam.x-i*stepu*2,cparam.y-i*stepv);
			pntArr1.append(data.oBaseSurf.evalPoint(param));
		}
		uvAv = AcGeNurbCurve3d(pntArr1);
		
		tmpC = uvAv.closestPointTo(data.oCenter);
		uvAv.isOn(tmpC,centerparam);
		//	centerparam = vc.paramOf(tmpC);
		uvAv.getInterval(intrvl);
		
		dist = uln*uln + vln*vln;
		dist = sqrt(dist);
		// 设置u参数展开计算值范围
		tmp = uvAv.paramAtLength(centerparam,dist,Adesk::kTrue);
		if (tmp==0) 
			tmp = intrvl.upperBound();
		data.oBaseSurf.isOn(uvAv.evalPoint(tmp),tParam2d);
		if (data.oEvalU.lowerBound() > tParam2d.x) {
			data.oEvalU.setLower(tParam2d.x);
		}
		if (data.oEvalV.lowerBound() > tParam2d.y) {
			data.oEvalV.setLower(tParam2d.y);
		}
	}
*/


	// u线和v线角中分线, 左上中
	nU = int ((cparam.x-intX.lowerBound())/stepu);
	nV = int ((intY.upperBound()-cparam.y)/stepv);
	len = nU>nV ? nV:nU;
	if (len) {
		pntArr1.setLogicalLength(0);
		for (i=0; i<len+1; i++) {
			param.set(cparam.x-i*stepu,cparam.y+i*stepv);
			pntArr1.append(data.oBaseSurf.evalPoint(param));
		}
		uvAv = AcGeNurbCurve3d(pntArr1);
		
		tmpC = uvAv.closestPointTo(data.oCenter);
		uvAv.isOn(tmpC,centerparam);
		//	centerparam = vc.paramOf(tmpC);
		uvAv.getInterval(intrvl);
		
		dist = uln*uln + vlp*vlp;
		dist = sqrt(dist);
		// 设置u参数展开计算值范围
		tmp = uvAv.paramAtLength(centerparam,dist,Adesk::kTrue);
		if (tmp==0) 
			tmp = intrvl.upperBound();
		data.oBaseSurf.isOn(uvAv.evalPoint(tmp),tParam2d);
		if (data.oEvalU.lowerBound() > tParam2d.x) {
			data.oEvalU.setLower(tParam2d.x);
		}
		if (data.oEvalV.upperBound() < tParam2d.y) {
			data.oEvalV.setUpper(tParam2d.y);
		}
	}
/*
	// u线和v线角中分线, 左上下
	nU = int ((cparam.x-intX.lowerBound())/(stepu*2));
	nV = int ((intY.upperBound()-cparam.y)/stepv);
	len = nU>nV ? nV:nU;
	if (len) {
		pntArr1.setLogicalLength(0);
		for (i=0; i<len+1; i++) {
			param.set(cparam.x-i*stepu*2,cparam.y+i*stepv);
			pntArr1.append(data.oBaseSurf.evalPoint(param));

⌨️ 快捷键说明

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