AcDb MPolygon-MPolygon内部的点可靠吗?
我一直在考虑使用AcDbMPolygon类和isPointInsideMPolygon()来验证一个点是否在一条轻量级折线内,但是由于某种原因对我不起作用。例如,我选择了一组多段线,如果我定义了一个内部点,我希望获得该多段线,即该内部点所在的位置。
下面是一个命令示例:
static void LESQGBPoly17_GETPOLY(void)
{
ads_name sspol;
resbuf *rbFilter = acutBuildList(RTDXF0, _T("LWPOLYLINE"), RTNONE);
if (acedSSGet(NULL, NULL, NULL, rbFilter, sspol) != RTNORM)
{
acutRelRb(rbFilter); return;
}
acutRelRb(rbFilter);
long len = 0;
if ((acedSSLength(sspol, &len) != RTNORM) || (len == 0))
{
acedSSFree(sspol); return;
}
AcGePoint3d worldPt;
if (acedGetPoint(NULL,_T("\nPick internal point: "),asDblArray(worldPt)) != RTNORM) return;
for (int i=0; i pPoly(objId, AcDb::kForWrite);//for write test to erase, or color change
if (pPoly.openStatus() == Acad::eOk)
{
acdbUcs2Wcs(asDblArray(worldPt),asDblArray(worldPt),false);
AcGeVector3d vDir = AcGeVector3d::kZAxis;
resbuf rb; acedGetVar(_T("viewdir"),&rb);
vDir = asVec3d(rb.resval.rpoint);
AcDb::Planarity plan_type;
AcGePlane plane;
pPoly->getPlane(plane,plan_type);
worldPt = worldPt.project(plane,vDir);
AcGeIntArray loopsArray; //loopsArray.setLogicalLength(0);
if (mpol.appendLoopFromBoundary(pPoly) == Acad::eOk)
{
if ( mpol.isPointInsideMPolygon(worldPt, loopsArray) > 0)
{
acutPrintf(_T("\nPoint inside..."));
pPoly.object()->setColorIndex(6);
}
}
}
}
acedSSFree(sspol);
}
但是,如果当我尝试在附着的图形中的洋红色多段线中定义内部点时,它不会返回true,除非我在isPointInsideMPolygon(worldPt,loopsArray,1.0)中更改容差以添加1.0,例如,它会返回该点在内部,但也会获得选择中的其他多段线(这是我不希望的)。所以现在,我很困惑...
有人有使用isPointInsideMPolygon()的经验吗?我知道Alexander Rivilis在这里发布的函数是_point_in_curve(),但它也有相同的结果...
谢谢!
**** Hidden Message ***** 乐,我有一个vba版本,但我还在努力把它转换成C#。
http://soft surfer . com orientation 2d _ Polygon()具有用于直线的数学运算
并且我添加了用于曲线的数学运算。 这可能与多边形的“缠绕”有关吗,即。它的顶点与围绕它的其他多边形的方向相反?如果是这种情况,那么它周围的所有多边形都将返回true。
只是一个猜测,但由于红色多边形在所有其他多边形中,这是您之前的多边形函数的结果,您可能需要反转顶点?
布莱科
我将研究该链接……我为我的gbpoly项目完成了一些功能,这些功能对这一点很有用,我希望它使用ARX类中可用的功能。
你好,米克;
根据adesk的arx新闻组中Alexander Rivilis的回答,似乎或者更确切地说,这是类中的一个错误。
谢谢! 半年前,我将此错误发布到ADN。有趣的是,在AutoCAD 2006中,此代码可以毫无问题地工作。新版本-新错误...
P. S.:尝试此代码:
static void BrepPointCheckPoint(void)
{
Acad::ErrorStatus es;
AcBr::ErrorStatus ebr;
ads_name en;
ads_point pt;
if (acedEntSel(_T("\nSelect contour: "), en, pt) != RTNORM)
return;
AcDbObjectId eId; acdbGetObjectId(eId,en);
AcDbObjectPointer pline(eId,AcDb::kForRead) ;
if ((es = pline.openStatus()) != Acad::eOk) {
acutPrintf(_T("\npline.openStatus()=%s"),acadErrorStatusText(es));
return;
}
if (acedGetPoint(pt,_T("\nPick point: "), pt) != RTNORM)
return;
AcDbVoidPtrArray ar, regions;
ar.append(pline.object());
if ((es = AcDbRegion::createFromCurves(ar,regions)) != Acad::eOk){
acutPrintf(_T("\nAcDbRegion::createFromCurves(ar,regions)=%s"),acadErrorStatusText(es));
return;
}
AcDbRegion reg; reg.copyFrom((AcDbRegion *)regions);
for (int i=0; i<regions.length();i++) delete regions;
AcBrBrep brEnt;ebr = brEnt.set(reg);
if (ebr != AcBr::eOk) {
acutPrintf(_T("\nbrEnt.set(sol)=%s"),acadErrorStatusText((Acad::ErrorStatus)(Adesk::UInt32)ebr));
return;
}
AcGe::PointContainment pDesc;
AcBrEntity *pCont = NULL;
AcBrBrepFaceTraverser brepFaceTrav; brepFaceTrav.setBrep(brEnt);
AcBr::ErrorStatus err = AcBr::eInvalidInput;
while (!brepFaceTrav.done()) {
AcBrFace brFace; brepFaceTrav.getFace(brFace);
err = brFace.getPointContainment(asPnt3d(pt),pDesc,pCont);
if (err == Acad::eOk && pDesc == AcGe::kInside) {
acedAlert(_T("In")); return;
} else if (err == Acad::eOk && pDesc == AcGe::kOnBoundary) {
acedAlert(_T("On")); return;
}
brepFaceTrav.next();
}
if (err == Acad::eOk) {
acedAlert(_T("Out"));
} else {
acedAlert(_T("Unknown error"));
}
return;
}
谢谢你,亚历山大
我稍后在家里尝试一下……我发现需要使用区域……
是的,它们会打开一个新孔来覆盖上一个孔……(用于虫子)
这是我最终使用的,它基于John F. Uhden
的算法编辑:函数isPointIn()现在可以用于封闭曲线类对象-Polyline(样条和拟合),LWPolyline(样条和拟合),圆圈和样条,添加了更多控件。-上传为CPP文件
LE! 在完成上一个函数之后,现在我已经能够提出自己的边界/ bpoly命令,名为GETPOLY,如果可以的话,看看正在进行的结果......现在我需要知道如何为C#传递这个新函数... 对猫来说很酷路易斯
页:
[1]
2