Author Topic: AcDbMPolygon - isPointInsideMPolygon Reliable ?  (Read 9131 times)

0 Members and 1 Guest are viewing this topic.

LE

  • Guest
AcDbMPolygon - isPointInsideMPolygon Reliable ?
« on: June 23, 2007, 11:34:36 am »
I been thinking of using the AcDbMPolygon class and the isPointInsideMPolygon() to verify if a point is inside a lightweight polyline, but for some reason is not working for me.

For example, I do a selection set of polylines, and if I define an internal point, I want to get the polyline, where that internal point was made.

Here is a sample command:
Code: [Select]
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<len; i++)
{
AcDbMPolygon mpol;
AcDbObjectId objId;
ads_name ename;
acedSSName(sspol, i, ename);
if (acdbGetObjectId(objId, ename) != Acad::eOk) return;
AcDbObjectPointer <AcDbPolyline> 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);
}


But, if when I try to define an internal point in the magenta polyline in the attached drawing, it won't return true, unless I change the tolerance in isPointInsideMPolygon(worldPt, loopsArray,1.0) to add the 1.0 for example, it will return that the point is inside, but also, will get the other polylines in the selection(something I do not want). So now, I am all confused... :-(

Anyone, have any experience using isPointInsideMPolygon() ? - I know Alexander Rivilis posted here the function is_point_in_curve(), but it also does the same results...


Thanks!

Bryco

  • Water Moccasin
  • Posts: 1770
Re: AcDbMPolygon - isPointInsideMPolygon Reliable ?
« Reply #1 on: June 24, 2007, 11:33:12 pm »
Le, I have a vba version that works but I'm still working on getting it to C#.
http://softsurfer.com   orientation2D_Polygon() has the math for straight plines
and I added the math for curves.

MickD

  • Gator
  • Posts: 2882
  • I don't need a job, I need Money!!
Re: AcDbMPolygon - isPointInsideMPolygon Reliable ?
« Reply #2 on: June 25, 2007, 12:25:46 am »
could it have something to do with the 'winding' of the polygon, ie. it's vertices are going the opposite way to the other poly's which are surrounding it? If this is the case then all the poly's around it would return true.
Just a guess but as that red poly is inside all the others as a result of your previous poly functions you may need to reverse the vertices??
"A language that doesn’t have everything is actually easier to program in than some that do."

        — Dennis M. Ritchie

LE

  • Guest
Re: AcDbMPolygon - isPointInsideMPolygon Reliable ?
« Reply #3 on: June 25, 2007, 09:10:07 am »
Le, I have a vba version that works but I'm still working on getting it to C#.
http://softsurfer.com   orientation2D_Polygon() has the math for straight plines
and I added the math for curves.

Bryco;

Thanks!

I'll look into that link... I have some functions done for my gbpoly project, and can be useful for this, I want it to use what it is available in the ARX classes.

LE

  • Guest
Re: AcDbMPolygon - isPointInsideMPolygon Reliable ?
« Reply #4 on: June 25, 2007, 09:11:40 am »
could it have something to do with the 'winding' of the polygon, ie. it's vertices are going the opposite way to the other poly's which are surrounding it? If this is the case then all the poly's around it would return true.
Just a guess but as that red poly is inside all the others as a result of your previous poly functions you may need to reverse the vertices??

Hi Mick;

Appears or better said it is a BUG in the class, according to an answer by Alexander Rivilis in the arx newsgroup of adesk.


Thanks!

Alexander Rivilis

  • Bull Frog
  • Posts: 205
  • Programmer from Kiev (Ukraine)
Re: AcDbMPolygon - isPointInsideMPolygon Reliable ?
« Reply #5 on: June 25, 2007, 09:56:14 am »
Appears or better said it is a BUG in the class, according to an answer by Alexander Rivilis in the arx newsgroup of adesk.
I post this bug half year ago to ADN. It is interesting that in AutoCAD 2006 this code work without problem.  New versions - new bugs... ;-)

P.S.: Try this code:
Code: [Select]
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<AcDbCurve> 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[0]);
  for (int i=0; i<regions.length();i++) delete regions[i];
  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;
}
« Last Edit: June 25, 2007, 10:10:58 am by Alexander Rivilis »

LE

  • Guest
Re: AcDbMPolygon - isPointInsideMPolygon Reliable ?
« Reply #6 on: June 25, 2007, 10:27:22 am »
Thank you Alexander;

I give it a try later at home... I see it is required the use of Regions :-( ....


And yes, they open a new hole to cover the previous one.... (for the bugs)
:)

LE

  • Guest
Re: AcDbMPolygon - isPointInsideMPolygon Reliable ?
« Reply #7 on: June 26, 2007, 05:45:45 pm »
Here is what I end up using, it is based on the algorithm by John F. Uhden

Edit: The function isPointInside() now can be use for closed Curve class objects - Polyline (spline and fit), LWPolyline (spline and fit), Circle and Spline, more control was added. - uploaded as CPP file

LE!
« Last Edit: June 27, 2007, 12:16:18 pm by LE »

LE

  • Guest
Re: AcDbMPolygon - isPointInsideMPolygon Reliable ?
« Reply #8 on: June 28, 2007, 01:00:23 am »
And after doing the previous function, now I have being able to come up with my own boundary/bpoly command named GETPOLY, if you can, have a look the in progress results... Now I need to know how to pass this new function for C#...

Bryco

  • Water Moccasin
  • Posts: 1770
Re: AcDbMPolygon - isPointInsideMPolygon Reliable ?
« Reply #9 on: June 28, 2007, 01:14:53 am »
Cool for cats Luis

LE

  • Guest
Re: AcDbMPolygon - isPointInsideMPolygon Reliable ?
« Reply #10 on: June 28, 2007, 10:07:39 am »
Cool for cats Luis

:)

Thanks!

It is part of an application, I been working, that will generate all the legal documentation of Condominium Projects.

T.Willey

  • Needs a day job
  • Posts: 5142
Re: AcDbMPolygon - isPointInsideMPolygon Reliable ?
« Reply #11 on: June 28, 2007, 11:09:59 am »
Looks good Luis!
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

LE

  • Guest
Re: AcDbMPolygon - isPointInsideMPolygon Reliable ?
« Reply #12 on: June 28, 2007, 11:39:30 am »
Looks good Luis!

Thank you Tim.

Have you read about on how to use an arx function in C#.... I remember seeing something of extern.... (talking nothing about COM, I do not have any experience with that)

The project it is to big to simple ported into C# (is not needed, but would like to use this function in some of my new C# routines) :)

T.Willey

  • Needs a day job
  • Posts: 5142
Re: AcDbMPolygon - isPointInsideMPolygon Reliable ?
« Reply #13 on: June 28, 2007, 11:56:54 am »
Looks good Luis!

Thank you Tim.

Have you read about on how to use an arx function in C#.... I remember seeing something of extern.... (talking nothing about COM, I do not have any experience with that)

The project it is to big to simple ported into C# (is not needed, but would like to use this function in some of my new C# routines) :)
Nope.  I haven't done any research yet.  Got busy at work, and at home was writing a paper for school.  If I could help in anyway let me know.
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

MickD

  • Gator
  • Posts: 2882
  • I don't need a job, I need Money!!
Re: AcDbMPolygon - isPointInsideMPolygon Reliable ?
« Reply #14 on: June 28, 2007, 06:09:42 pm »
Luis, looks good!

Is this routine just a function or is it all part of a class/classes?
The reason I ask is it is dead easy to make a .net wrapper for functions, just create a managed application, add your function header file and add the function to a class as a member.

Have a look into the managed arx header (I can't remember its name just now) for clues and routines to pass data/object id's back and forward from managed/unmanaged and back. That should be all you need.
Good luck!
"A language that doesn’t have everything is actually easier to program in than some that do."

        — Dennis M. Ritchie

LE

  • Guest
Re: AcDbMPolygon - isPointInsideMPolygon Reliable ?
« Reply #15 on: June 29, 2007, 10:51:55 pm »
Here is the function ported to C#, HTH

Includes some functions taken from the MgdDbg SLN by Jim Awe from AutoDesk.


Oops... forgot to include this:

Code: [Select]
const Double pi = Math.PI;
public static Double dVal = 0.2;
public static readonly Point3d kOrigin = new Point3d(0.0, 0.0, 0.0);
public static readonly Vector3d kXAxis = new Vector3d(1.0, 0.0, 0.0);
public static readonly Vector3d kYAxis = new Vector3d(0.0, 1.0, 0.0);
public static readonly Vector3d kZAxis = new Vector3d(0.0, 0.0, 1.0);

static Double delta(Double a1, Double a2)
{
    Double ang;
    if (a1 > a2 + pi)
        ang = (a2 + pi + pi) - a1;
    else if (a2 > a1 + pi)
        ang = a2 - a1 - pi - pi;
    else
        ang = a2 - a1;
    return ang;
}
« Last Edit: June 29, 2007, 11:27:10 pm by LE »

bikelink

  • Newt
  • Posts: 98
Re: AcDbMPolygon - isPointInsideMPolygon Reliable ?
« Reply #16 on: June 11, 2010, 05:01:17 am »
very very good.

davidwkj

  • Mosquito
  • Posts: 1
Re: AcDbMPolygon - isPointInsideMPolygon Reliable ?
« Reply #17 on: August 18, 2015, 07:02:00 am »
And after doing the previous function, now I have being able to come up with my own boundary/bpoly command named GETPOLY, if you can, have a look the in progress results... Now I need to know how to pass this new function for C#...

wonderful work! It is really helpful~