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