Curve Containment Test issue

Hello,
I need to verify if two closed curves are one in the other but in the attached example it seems that the RhinoPlanarClosedCurveContainmentTest function returns a wrong result.
If I move the curves or enlarge/reduce the tolerance it works.

RhinoPlanarClosedCurveContainmentTest.3dm (39.5 KB)

My code is the following:

CRhinoCommand::result CCommandNest3::RunCommand( const CRhinoCommandContext& context )
{
	CRhinoGetObject go;
	go.SetCommandPrompt(L"Select curves");
	go.SetGeometryFilter(CRhinoGetObject::curve_object);
	go.GetObjects(2, 2);
	if (go.CommandResult() != CRhinoCommand::success)
		return go.CommandResult();

	const ON_Curve* curve1 = go.Object(0).Curve();
	if (nullptr == curve1)
		return CRhinoCommand::failure;

	const ON_Curve* curve2 = go.Object(1).Curve();
	if (nullptr == curve2)
		return CRhinoCommand::failure;

	CRhinoView* view = go.View();
	if (nullptr == view)
		return CRhinoCommand::failure;

	double tolerance = 1E-3;
	const int res =
		RhinoPlanarClosedCurveContainmentTest(
			*curve1,
			*curve2,
			ON_xy_plane,
			tolerance);

	if (res == 3 || res == 2)
	{
		return CRhinoCommand::success;
	}
	else
	{
		return CRhinoCommand::failure;
	}
}

Could you help me to check the problem?

my Rhino6 sdk version is 6.0.18012.13241
Rhino6 version is 6.19.19295.01001

Thanks you!

Hi @margari,

Let me know of this SDK sample helps.

cmdSampleClosedCurveContainment.cpp

– Dale

Hi @dale,
your sample works fine but if I set the DocProperties tolerance at 0.001 unit (instead of 0.01 unit) and use the ON_xy_plane, then the RhinoPlanarClosedCurveContainmentTest returns 0.
I used the following code:

CRhinoCommand::result CCommandSampleClosedCurveContainment::RunCommand(const CRhinoCommandContext& context)
{
	CRhGetPlanarClosedCurve go(context.m_doc.AbsoluteTolerance());
	go.SetCommandPrompt(L"Select two closed planar curves for containment test");
	go.GetObjects(2, 2);
	if (go.CommandResult() != CRhinoCommand::success)
		return go.CommandResult();

	const ON_Curve* curve0 = go.Object(0).Curve();
	const ON_Curve* curve1 = go.Object(1).Curve();
	if (nullptr == curve0 || nullptr == curve1)
		return CRhinoCommand::failure;

	const double tolerance = context.m_doc.AbsoluteTolerance();

	ON_Plane plane0, plane1;
	if (!curve0->IsPlanar(&plane0, tolerance) || !curve1->IsPlanar(&plane1, tolerance))
		return CRhinoCommand::failure;

	if (!curve0->IsInPlane(ON_xy_plane, tolerance) || !curve1->IsInPlane(ON_xy_plane, tolerance))
	{
		RhinoApp().Print(L"Curves are not in XY-plane.\n");
		return CRhinoCommand::success;
	}

	const int rc = RhinoPlanarClosedCurveContainmentTest(*curve0, *curve1, ON_xy_plane, tolerance);
	if (rc == 0)
		RhinoApp().Print(L"The regions bounded by the curves are disjoint.\n");
	else if (rc == 1)
		RhinoApp().Print(L"The two curves intersect.\n");
	else if (rc == 2)
		RhinoApp().Print(L"The region bounded by the first curve is inside of the second curve.\n");
	else
		RhinoApp().Print(L"The region bounded by the second curve is inside of the first curve.\n");

	return CRhinoCommand::success;
} 

I can get around the problem using the IsPlanar function instead of using ON_xy_plane but I’ll be glad to understand what is the problem. It is odd that with a smaller tolerance it doesn’t work, isn’t it? It should be more accurate, I suppose.

Thank you for your propmt support!

Hi @margari,

Looks like some of the curve control points have some floating noice, as their z-coordinate is not exactly 0.0. You might consider projecting curves onto the world xy-plane.

– Dale

Ok, I’ll do so

thank you!