📄 geutilities.cpp
字号:
#include "stdafx.h"
#include "stdarx.h"
#include <MATH.H>
#include "GeUtilities.h"
#include "BrUtilities.h"
#include "CreateDbObj.h"
#include "DbUtilities.h"
void getPntsFromSpline(AcDbSpline *spl,AcGePoint3dArray& pnts)
{
int i,num;
if (spl->hasFitData()) {
num = spl->numFitPoints();
pnts.setLogicalLength(num);
for (i=0; i<num; i++) {
spl->getFitPointAt(i,pnts[i]);
}
} else {
int degree;
Adesk::Boolean bTmp;
AcGePoint3dArray tPnts;
AcGeDoubleArray weights,knots;
double dTmp,dTol;
spl->getNurbsData(degree,bTmp,bTmp,bTmp,tPnts,knots,weights,dTmp,dTol);
num = knots.length();
pnts.setLogicalLength(num);
int j = 0;
spl->getPointAtParam(knots[0],pnts[0]);
for (i=1; i<num; i++) {
if (fabs(knots[i]-knots[i-1]) > dTol) {
j++;
spl->getPointAtParam(knots[i],pnts[j]);
}
}
pnts.setLogicalLength(j+1);
}
}
void getPntsFromSpline(AcDbSpline *spl,AcGePoint3dArray& pnts,int pointnum)
{
int i,num;
if (spl->hasFitData()) {
num = spl->numFitPoints();
pnts.setLogicalLength(num);
for (i=0; i<num; i++) {
spl->getFitPointAt(i,pnts[i]);
}
} else {
int degree;
Adesk::Boolean bTmp;
AcGePoint3dArray tPnts;
AcGeDoubleArray weights,knots;
double dTmp,dTol;
spl->getNurbsData(degree,bTmp,bTmp,bTmp,tPnts,knots,weights,dTmp,dTol);
num = knots.length();
if (num<pointnum && pointnum>2) {
double minKnot,maxKnot,step;
minKnot = knots[0];
maxKnot = knots[num-1];
step = (maxKnot-minKnot)/(pointnum-1);
knots.setLogicalLength(pointnum);
num = pointnum;
knots[0] = minKnot;
for (i=1; i<num; i++) {
knots[i] = knots[i-1] + step;
}
}
pnts.setLogicalLength(num);
int j = 0;
spl->getPointAtParam(knots[0],pnts[0]);
for (i=1; i<num; i++) {
if (fabs(knots[i]-knots[i-1]) > dTol) {
j++;
spl->getPointAtParam(knots[i],pnts[j]);
}
}
pnts.setLogicalLength(j+1);
}
}
bool
getPntsFromCurve(AcDbCurve *pCurve,
AcGePoint3dArray& pnts,
int numPoint)
{
if ( numPoint<0
|| numPoint==1
|| !pCurve->isA()) return false;
pnts.setLogicalLength(0);
AcDbSpline *spl;
if (pCurve->getSpline(spl) == Acad::eOk) {
if (numPoint==0) {
getPntsFromSpline(spl,pnts);
} else {
getPntsFromSpline(spl,pnts,numPoint);
}
delete spl;
return true;
}
if (pCurve->isKindOf(AcDbLine::desc())) { // LINE
AcDbLine *pLine;
pLine = AcDbLine::cast(pCurve);
if (numPoint==0) {
pnts.append(pLine->startPoint());
pnts.append(pLine->endPoint());
} else {
double start,step;
AcGePoint3d pnt;
pLine->getStartParam(start);
pLine->getEndParam(step);
step = (step-start)/(numPoint-1);
for (register i=0; i<numPoint; i++) {
pLine->getPointAtParam(start,pnt);
pnts.append(pnt);
start = start + step;
}
}
return true;
}
if (pCurve->isKindOf(AcDbPolyline::desc())) { // LWPOLYLINE
AcDbPolyline *pPLine;
AcGePoint3d pnt;
pPLine = AcDbPolyline::cast(pCurve);
int len;
len = pPLine->numVerts();
for (register i=0; i<len; i++) {
pPLine->getPointAt(i,pnt);
pnts.append(pnt);
}
return true;
}
return false;
}
bool
getPntsFromCurve(AcGeCurve3d *pCurve,
AcGePoint3dArray& pnts,
int numPoint)
{
if ( numPoint<0
|| numPoint==1 ) return false;
pnts.setLogicalLength(0);
AcGe::EntityId type;
type = pCurve->type();
AcGeCurve3d *pNative;
bool bNative = false;
if (type == AcGe::kExternalCurve3d) {
if (((AcGeExternalCurve3d*)pCurve)->isNativeCurve(pNative)) {
bNative = true;
type = pNative->type();
} else {
return false;
}
} else {
pNative = pCurve;
}
switch(type) {
case AcGe::kLineSeg3d :
if (numPoint==0) {
pnts.setLogicalLength(2);
pNative->hasStartPoint(pnts[0]);
pNative->hasEndPoint(pnts[1]);
} else {
pNative->getSamplePoints(numPoint,pnts);
}
break;
case AcGe::kCircArc3d :
case AcGe::kEllipArc3d :
if (numPoint == 0) {
pNative->getSamplePoints(9,pnts);
} else {
pNative->getSamplePoints(numPoint,pnts);
}
break;
case AcGe::kNurbCurve3d :
getPntsFromSpline(*(AcGeNurbCurve3d*)pNative,pnts,numPoint);
break;
case AcGe::kPolyline3d :
AcGePolyline3d *pPoly;
pPoly = (AcGePolyline3d*)pNative;
int i,len;
len = pPoly->numControlPoints();
pnts.setLogicalLength(len);
for (i=0; i<len; i++) {
pnts[i] = pPoly->controlPointAt(i);
}
break;
default:
if (bNative) delete pNative;
return false;
}
if (bNative) delete pNative;
return true;
}
int minArr(const AcGeDoubleArray& arr)
{
int pos=0,i;
double min = arr[0];
for(i=1;i<arr.length();i++) {
if(arr[i]<min) {
min = arr[i];
pos = i;
}
}
return pos;
}
int maxArr(const AcGeDoubleArray& arr)
{
int pos=0,i;
double max = arr[0];
for(i=1;i<arr.length();i++) {
if(arr[i]>max) {
max = arr[i];
pos = i;
}
}
return pos;
}
int Round(const double& x)
{
if (x>0) {
return int(x+0.5f);
} else {
return int(x-0.5f);
}
}
double triangleArea(const AcGePoint2d& p1, const AcGePoint2d& p2, const AcGePoint2d& p3)
{
double area;
AcGeMatrix3d mat1;
mat1.setCoordSystem(AcGePoint3d(0.0f,0.0f,0.0f),AcGeVector3d(p1.x,p2.x,p3.x),
AcGeVector3d(p1.y,p2.y,p3.y),AcGeVector3d(1.0f,1.0f,1.0f));
area = mat1.det()/2.0;
return area;
}
double triangleArea(const AcGePoint3d& p1, const AcGePoint3d& p2, const AcGePoint3d& p3)
{
double area,a1,a2,a3;
AcGeMatrix3d mat1;
mat1.setCoordSystem(AcGePoint3d(0.0f,0.0f,0.0f),AcGeVector3d(p1.x,p2.x,p3.x),
AcGeVector3d(p1.y,p2.y,p3.y),AcGeVector3d(1.0f,1.0f,1.0f));
a1 = mat1.det();
mat1.setCoordSystem(AcGePoint3d(0.0f,0.0f,0.0f),AcGeVector3d(p1.y,p2.y,p3.y),
AcGeVector3d(p1.z,p2.z,p3.z),AcGeVector3d(1.0f,1.0f,1.0f));
a2 = mat1.det();
mat1.setCoordSystem(AcGePoint3d(0.0f,0.0f,0.0f),AcGeVector3d(p1.z,p2.z,p3.z),
AcGeVector3d(p1.x,p2.x,p3.x),AcGeVector3d(1.0f,1.0f,1.0f));
a3 = mat1.det();
area = sqrt(a1*a1+a2*a2+a3*a3)/2.0;
return area;
}
void reverse(ChGePnts2dArray& pntsArr)
{
int i,len;
len = pntsArr.length();
for (i=0; i<len; i++) {
pntsArr[i].reverse();
}
if (len>1) {
pntsArr.reverse();
}
}
void reverse(ChGePnts3dArray& pntsArr)
{
int i,len;
len = pntsArr.length();
for (i=0; i<len; i++) {
pntsArr[i].reverse();
}
if (len>1) {
pntsArr.reverse();
}
}
// 判断矢量vec1到vec2的方向是否为顺时针
Adesk::Boolean isClockwise(const AcGeVector2d& vec1, const AcGeVector2d& vec2)
{
AcGeVector3d vec3d1(vec1.x,vec1.y,0),vec3d2(vec2.x,vec2.y,0);
Adesk::Boolean bRet;
bRet = AcGeVector3d::kZAxis.isCodirectionalTo(
vec3d2.crossProduct(vec3d1));
return bRet;
}
// 判断点是否在直线的右手边
Adesk::Boolean isClockwise(const AcGeLine2d& line, const AcGePoint2d& pnt)
{
AcGePoint2d perpPnt;
AcGeLine2d perpLine,dirLine;
line.getPerpLine(pnt,perpLine);
line.intersectWith(perpLine,perpPnt);
dirLine.set(perpPnt,pnt);
return !perpLine.direction().isCodirectionalTo(dirLine.direction());
}
// 判断点是否在直线的右手边
Adesk::Boolean isClockwise(const AcGePoint2d& pnt,const AcGePoint2d& p1,const AcGePoint2d& p2)
{
AcGePoint2d perpPnt;
AcGeLine2d perpLine,dirLine;
AcGeLine2d line(p1,p2);
line.getPerpLine(pnt,perpLine);
line.intersectWith(perpLine,perpPnt);
dirLine.set(perpPnt,pnt);
return !perpLine.direction().isCodirectionalTo(dirLine.direction());
}
// 判断曲面上点相对曲线的方向,true右或false左
bool isClockwise(const AcGeNurbSurface& surf,const AcGePoint3dArray& curve,const AcGePoint3d& dirPnt)
{
// 参数平面上的点
AcGePoint2dArray curve2d;
AcGePoint2d dirPnt2d;
AcGePoint3d pnt;
int i,len;
len = curve.length();
if (!len) return false;
AcGePoint2d tParam2d;
for (i=0; i<len; i++) {
pnt = surf.closestPointTo(curve[i]);
surf.isOn(pnt,tParam2d);
curve2d.append(tParam2d);
}
pnt = surf.closestPointTo(dirPnt);
surf.isOn(pnt,dirPnt2d);
// dirPnt2d = surf.paramOf(pnt);
bool bDirRight = false;
AcGeNurbCurve2d spl(curve2d);
if (isClockwise(dirPnt2d,spl)) {
bDirRight = true;
}
return bDirRight;
}
// 由三点得到平面,当返回值Acad::eOk时返回的pln才有意义
Acad::ErrorStatus getPlaneFrom3Pnts(const AcGePoint3dArray& pnts,AcGePlane& pln)
{
if(pnts.length()!=3) return Acad::eInvalidInput;
AcGeVector3d vec1,vec2;
AcGePoint3d p1,p2,p;
vec1 = pnts[1]-pnts[0];
vec2 = pnts[2]-pnts[0];
vec1 = vec1.crossProduct(vec2);
pln.set(pnts[0],vec1);
pln.get(p1,p,p2);
if(p1.isEqualTo(AcGePoint3d(0.0f,0.0f,0.0f))) return Acad::eInvalidInput;
else return Acad::eOk;
}
// 由三点得到平面,当返回值Acad::eOk时返回的pln才有意义
Acad::ErrorStatus getPlaneFrom3Pnts(const AcGePoint3d& pp1, const AcGePoint3d& pp2,
const AcGePoint3d& pp3,AcGePlane& pln)
{
AcGePoint3dArray pnts;
pnts.append(pp1);
pnts.append(pp2);
pnts.append(pp3);
AcGeVector3d vec1,vec2;
AcGePoint3d p1,p2,p;
vec1 = pnts[1]-pnts[0];
vec2 = pnts[2]-pnts[0];
vec1 = vec1.crossProduct(vec2);
pln.set(pnts[0],vec1);
pln.get(p1,p,p2);
if(p1.isEqualTo(AcGePoint3d(0.0f,0.0f,0.0f))) return Acad::eInvalidInput;
else return Acad::eOk;
}
// 判断点相对于线段的位置,平面
int pointPosToLine(const AcGePoint2d& p,const AcGePoint2d& p1,const AcGePoint2d& p2)
{
AcGeVector2d vec1,vec2;
double angle;
if(p.isEqualTo(p1)) return 1; // 点与线段第一点重合
if(p.isEqualTo(p2)) return 2; // 点与线段第二点重合
vec1 = p1-p;
vec2 = p2-p;
angle = vec1.angleTo(vec2);
if(fabs(angle-PI)<TOL) return 0; // 点在线段上
else if(angle<TOL) return 3; // 点在线段延长线上
else return -1; // 点在线段外
}
// 判断点相对于线段的位置,空间
int pointPosToLine(const AcGePoint3d& p,const AcGePoint3d& p1,const AcGePoint3d& p2)
{
AcGeVector3d vec1,vec2;
double angle;
if(p.isEqualTo(p1)) return 1; // 点与线段第一点重合
if(p.isEqualTo(p2)) return 2; // 点与线段第二点重合
vec1 = p1-p;
vec2 = p2-p;
angle = vec1.angleTo(vec2);
if(fabs(angle-PI)<TOL) return 0; // 点在线段上
else if(fabs(angle)<TOL) return 3; // 点在线段延长线上
else return -1; // 点在线段外
}
// 判断点相对于三角形的位置
int pointPosToTriangle(const AcGePoint2d& pnt,AcGePoint2dArray& pnts)
{
int pos;
if (pnts.length()<3) return -1; // 不是三角形
if(pnt.isEqualTo(pnts[0])) return 1; // 点与三角形第一点重合
if(pnt.isEqualTo(pnts[1])) return 2; // 点与三角形第二点重合
if(pnt.isEqualTo(pnts[2])) return 3; // 点与三角形第三点重合
pos = pointPosToLine(pnt,pnts[0],pnts[1]);
if(pos==0) return 4;
else if(pos==3) return -1;
pos = pointPosToLine(pnt,pnts[1],pnts[2]);
if(pos==0) return 5;
else if(pos==3) return -1;
pos = pointPosToLine(pnt,pnts[2],pnts[0]);
if(pos==0) return 6;
else if(pos==3) return -1;
if(isClockwise(pnt,pnts[0],pnts[1])) return -1;
if(isClockwise(pnt,pnts[1],pnts[2])) return -1;
if(isClockwise(pnt,pnts[2],pnts[0])) return -1;
return 0;
}
// 由面积等比原则,通过三角形p1p2p3内一点p4,及对应得三角形r1r2r3,得出对应的点r4
bool mapPointInTriangle(AcGePoint2dArray& pnts1,AcGePoint2dArray& pnts2)
{
if (pnts1.length()!=4 || pnts2.length()!=4) return false;
double sigma[3],A,B,C,D,E,F,x,y;
sigma[0] = triangleArea(pnts1[0],pnts1[1],pnts1[3]);
sigma[1] = triangleArea(pnts1[1],pnts1[2],pnts1[3]);
sigma[2] = triangleArea(pnts1[2],pnts1[0],pnts1[3]);
A = (pnts2[1].y-pnts2[2].y)*sigma[2] - (pnts2[2].y-pnts2[0].y)*sigma[1];
B = (pnts2[1].x-pnts2[2].x)*sigma[2] - (pnts2[2].x-pnts2[0].x)*sigma[1];
C = (pnts2[1].x*pnts2[2].y-pnts2[2].x*pnts2[1].y)*sigma[2] -
(pnts2[2].x*pnts2[0].y-pnts2[0].x*pnts2[2].y)*sigma[1];
D = (pnts2[0].y-pnts2[1].y)*sigma[1] - (pnts2[1].y-pnts2[2].y)*sigma[0];
E = (pnts2[0].x-pnts2[1].x)*sigma[1] - (pnts2[1].x-pnts2[2].x)*sigma[0];
F = (pnts2[0].x*pnts2[1].y-pnts2[1].x*pnts2[0].y)*sigma[1] -
(pnts2[1].x*pnts2[2].y-pnts2[2].x*pnts2[1].y)*sigma[0];
x = (C*E-B*F)/(B*D-A*E);
y = (C*D-A*F)/(B*D-A*E);
pnts2[3].set(x,y);
return true;
}
// 由等比原则,通过, 线段p1p2内一点p3,及对应的线段r1r2,得出r1r2上对应的点r3
void mapPointInLine(AcGePoint2dArray& pnts1,AcGePoint2dArray& pnts2)
{
double sc;
sc = (pnts1[2]-pnts1[0]).length()/(pnts1[1]-pnts1[0]).length();
pnts2[2] = pnts2[0] + (pnts2[1]-pnts2[0])*sc;
}
// 由等比原则,通过, 线段p1p2内一点p3,及对应的线段r1r2,得出r1r2上对应的点r3
void mapPointInLine(AcGePoint3dArray& pnts1,AcGePoint2dArray& pnts2)
{
double sc;
sc = (pnts1[2]-pnts1[0]).length()/(pnts1[1]-pnts1[0]).length();
pnts2[2] = pnts2[0] + (pnts2[1]-pnts2[0])*sc;
}
// 由等比原则,通过, 线段p1p2内一点p3,及对应的线段r1r2,得出r1r2上对应的点r3
void mapPointInLine(AcGePoint2dArray& pnts1,AcGePoint3dArray& pnts2)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -