C# ClosestIndexInList Method Error

Hi all,

I have a cloud of points and a given point called B. I want to find the closest point from the cloud to point B.

Like @DavidRutten suggested here I am trying to use the method:
Point3dList.ClosestIndex Method
https://developer.rhino3d.com/api/RhinoCommon/html/M_Rhino_Collections_Point3dList_ClosestIndex.htm

My code:

Point3d FirstPoint = iPoints[iPoints.ClosestIndexInList(iStartPoint)];
a = FirstPoint;

For some reason I get this error:

  1. Error (CS1061): ‘System.Collections.Generic.List<Rhino.Geometry.Point3d>’ does not contain a definition for ‘ClosestIndexInList’ and no extension method ‘ClosestIndexInList’ accepting a first argument of type ‘System.Collections.Generic.List<Rhino.Geometry.Point3d>’ could be found (are you missing a using directive or an assembly reference?) (line 58)

Which basically says, that data type List has not method called ClosestIndexInList. And that it does not take as an input the data type List. Which makes no sense:

  1. Because ClosestIndexInList IS a List method
  2. Because I never passed a List type as an input of ClosestIndexInList I passed in a Point3d type.

You can clearly see that ‘iStartPoint’ is a Point3d type!

Hi, note David says it is a “static” method.
Your iPoints is indeed an instance of Point3dList. However, a static method is not hanging under an instance but it is hanging from it’s original class, Point3dList in your case. As David says, ClosestIndex is just a method, so it’s hanging from an instance.
The code should look like this.

Hi, thank you.

I am not sure I follow your explanation: I am using ClosestIndexInList which is, in fact, static. Meaning I don’t need to create an instance of a class to utilize it. In fact David says just that:

If I get this right, I should be able to just call it directly on a List<Point3d> type.
As in:

Point3d myPoint = new Point3d();
List<Point3d> myList = new List<Point3d> ();
myList.ClosestIndexInList(myPoint)

Or I am just totally confused… :worried:

Hi, maybe I was not right and a static method can be called via an instance.
But all of those methods are the methods of Point3dList, which is different from List.
You need to create a Point3dList from a List first. Point3dList is hanging from Rhino.Collections.

The inputs are specified as generic IEnumerable meaning you can feed either List or Point3dList. But the methods themselves are the methdos of Point3dList, not List

Right, I am using Poit3dList, I specified it on the inputs for the C# component: List Access and Type Hint: Point3d :man_shrugging:

This is all you need :smiley:
Rhino.Collections.Point3dList pointlist=new Rhino.Collections.Point3dList(iPoints);

You are confusing a list of Point3d with the Point3dList class :smiley: confusing naming but not the same thing. You can imagine the Point3dList class like a group. It lets a list of points be treated like a single object so you can do things to the points without iterating.

1 Like

Yes! I was just starting to realize that by looking at the documentation. Thanks!

What I don’t get is what David said, that I can use ClosestIndexInList and ClosestPointInList on other collections such as List <Point3d>. Is that a fair statement if first I need to convert my List<Point3d> into a Point3dList?

That means the first parameter of
Rhino.Collections.Point3dList.ClosestPointIndexInList(param1,pnt);
does not need to be Point3dList but can also take List

It’s confusing. Welcome to the hell. :stuck_out_tongue_winking_eye:

1 Like

Heeeey, now I realized why ShunnSup never understood what I was trying to say.
By some reason, “LIst< Point3d >” was cleaned by the forum system and only “List” was shown. Why is this??

<> is some kind of discourse formatting.

you can use triple ticks at the beginning and end to format code ```

1 Like

Oh, it means you can just pass in a List<Point3d> instead of a PointList3d

That’s a twisted way of looking at “static” that I never saw anywhere. :sweat_smile:

From stack overflow:
You can do this to execute a static method:

MyClass.staticMethod(); //Simply refers to the class's static code
//

But to execute a non-static method, you must do this:

MyClass obj = new MyClass(); //Create an instance
obj.nonstaticMethod(); //Refer to the instance's class's code

PD: I also use `` with the word in the middle to avoid List<Point3d> being formatted to List.

Oh, it means you can just pass in a List<Point3d> instead of a PointList3d

Actually no, what David means is you can just use the method directly without having to make a Point3dList, for instance.

private void RunScript(Point3d iStartPoint, List<Point3d> iPoints, ref object A)
  {
    Point3d firstPoint = Point3dList.ClosestPointInList(iPoints, iStartPoint);
    A = firstPoint;
  }
1 Like

Thank you guys, everything cleared up! :smiling_face_with_three_hearts:

Also, don’t forget to add using Rhino.Collections;
image

1 Like

I think I had it working without it Micheal :thinking: but double proof is always good!

for me it cant find the method and throws an error without adding that (in R6). R5 has that using statement there by default.

No you are right! I was using @mikity_kogekoge code, which already types in the complete namespace instead of adding using Rhino.Collections;

1 Like

If you have a really large number of points it may also be worth considering PointCloud.ClosestPoint

https://developer.rhino3d.com/api/RhinoCommon/html/M_Rhino_Geometry_PointCloud_ClosestPoint.htm

I wonder what the threshold is for when its worth switching from PointList3d to PointCloud.

1 Like