- UID
- 1
- 积分
- 15892
- 精华
- 贡献
-
- 威望
-
- 活跃度
-
- D豆
-
- 在线时间
- 小时
- 注册时间
- 2002-1-3
- 最后登录
- 1970-1-1
|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
How to create a new 2D polyline in 3D space?
ID 17257
Applies to: AutoCAD 2000I
AutoCAD 2002
AutoCAD 2000
Date 1/23/2002
This document is part of Coordinates and Transformations Polyline AcGe (Geometry Library) ObjectARX
Question
How do I create a 2d polyline with a set of 3d points that lie in a plane?
Answer
The following code sample does this, please find the whole project attached.
下面的代码,朋友们可以提取几个有用的公共函数,如根据一个点数组中的所有3D点得到他们组成平面的NORMAL向量, 添加对象到块表记录中等等.
[php]
Adesk::Boolean obtainNormal( AcGePoint3dArray &wcsPts, AcGeVector3d &normal )
{
/* Function endeavors to form 2 non-colinear vectors from points
in the wcsPts array.
Once found, the vectors comprise a plane and a normal can be calculated.
This plane normal must then be perpendicular to vectors formed from
the remaining points in wcsPts */
AcGeVector3d xAxis = AcGeVector3d::kIdentity;
normal = AcGeVector3d::kIdentity;
int nPts = wcsPts.length();
for( int i=0; i < nPts ; i++ ) {
AcGeVector3d vec = wcsPts[(i+1)%nPts] - wcsPts;
if( vec.isZeroLength() )
continue;
else if( !normal.isZeroLength() ) {
if( vec.isPerpendicularTo( normal ))
continue;
else
return Adesk::kFalse;
}
else if( xAxis.isZeroLength() )
xAxis = vec;
else if( !xAxis.isParallelTo(vec ) ) {
normal = xAxis.crossProduct( vec ).normal();
}
}
if( normal.isZeroLength() ) {
if( xAxis.isZeroLength() )
normal = AcGeVector3d::kZAxis;
else
normal = xAxis.perpVector();
}
return Adesk::kTrue;
}
Adesk::Boolean
gatherPoints( AcGePoint3dArray &wcsPts, AcGeVector3d &normal )
{
ads_point prevPt;
ads_point newPt;
while( ads_getpoint(wcsPts.length() == 0 ? NULL : prevPt, "\nEnter point
", newPt ) == RTNORM ) {
acdbUcs2Wcs(newPt, newPt, Adesk::kFalse );
wcsPts.append( asPnt3d( newPt ) );
asPnt3d( prevPt ) = asPnt3d( newPt );
int nPts = wcsPts.length();
if( nPts >= 2 ) {
ads_point fromPt, toPt;
asPnt3d(fromPt) = wcsPts[nPts-2];
acdbWcs2Ucs(fromPt,fromPt,Adesk::kFalse );
asPnt3d(toPt) = wcsPts[nPts-1];
acdbWcs2Ucs(toPt,toPt,Adesk::kFalse );
ads_grdraw(fromPt, toPt, 1, 0);
}
}
return obtainNormal( wcsPts, normal );
}
void
constructPolyArx( AcGePoint3dArray &wcsPts, AcGeVector3d &normal,
AcDbPolyline*&pPoly)
{
int nPts = wcsPts.length();
pPoly = new AcDbPolyline( nPts );
pPoly->setNormal(normal );
AcGeMatrix3d mat;
AcGeVector3d xAxis = normal.perpVector();
AcGeVector3d yAxis = normal.crossProduct(xAxis);
// need to transform pts from WCS into UCS of plane:
// ucsPt = ucsMat.inverse() * wcsPt
mat.setCoordSystem(
AcGePoint3d::kOrigin,
xAxis, yAxis, normal );
mat = mat.inverse();
for( int i=0; i < nPts; i++ ) {
AcGePoint2d pt2d;
AcGePoint3d pt3d;
pt3d = mat * wcsPts;
if( i==0 )
pPoly->setElevation(pt3d.z);
pt2d.x = pt3d.x;
pt2d.y = pt3d.y;
if( i == nPts-1 && wcsPts == wcsPts[0] )
pPoly->setClosed(Adesk::kTrue );
else
pPoly->addVertexAt(i, pt2d );
}
return;
}
Adesk::Boolean
postToMs( AcDbEntity*pEnt)
{
AcDbBlockTable* pBT;
if (Acad::eOk != acdbCurDwg()->getBlockTable( pBT, AcDb::kForRead ))
return Adesk::kFalse;
AcDbBlockTableRecord* pBTR;
Acad::ErrorStatus es =
pBT->getAt( ACDB_MODEL_SPACE, pBTR, AcDb::kForWrite );
pBT->close();
if (Acad::eOk != es)
return Adesk::kFalse;
es = pBTR->appendAcDbEntity( pEnt );
pBTR->close();
return (Acad::eOk == es);
}
void utilsmyarxpoly()
{
// TODO: add your code here
// function to gather 3d points, and make into a 2d polyline
AcGePoint3dArray wcsPts;
AcGeVector3d normal;
Adesk::Boolean planar = gatherPoints( wcsPts, normal );
if( !planar || wcsPts.length() < 1 )
return;
AcDbPolyline*pPoly;
constructPolyArx(wcsPts, normal, pPoly );
postToMs( pPoly );
pPoly->close();
// end of function
}
// TODO: add your other functions here
// END
[/php] |
|