Grasshopper

algorithmic modeling for Rhino

Hi,


I'm having trouble figuring out how to compare curves with ghPython.

I'm trying to compare two lists of curves, and filter those that are in one list but not the other.

However, it seems that grasshopper / rhino is very picky about equality - if the same curve is stored in two different components, those two representations are not equal.

In fact, even if they're in the same component, but are passed as separate variables into the ghPython component, they're not recognized as equal.

Is there a method that can get around this / am I interpreting things incorrectly?

I've attached a gh file that demonstrates the problem.

Views: 2377

Attachments:

Replies to This Discussion

Does nobody have an answer? This seems like a pretty fundamental issue.

My solution was to write a function that compares the control points of each curve, and if they are all the same, declares the curves equal. I'm curious why this isn't the way Rhino tests for equality - points can be tested for equality, but the curve equality function right now seems completely useless (or worse)

def compare_curves(x, y):
  px = x.Points
  py = y.Points
  if px.Count != py.Count: return False

  for p1, p2 in zip(px, py):
    if p1 != p2: return False
  return True

Hi Christopher,

Due to floating point limitations, it is not a good practice to compare two numbers with equality, without tolerance included. The same goes for points, which coordinates are floats too. Use the EpsilonEquals method.

As for your comparing curves issue:

You can not compare two curves, by simply checking for equality. Comparing their control points is not an accurate approach too.
What you should do is check the curvature and tangent vectors along these two. Take a look at this script.

Hi Djordje,

Thanks for the response - very useful information.

It seems like you are comparing curves using the EpsilonEquals method in your code - what does this method do if it's not a valid comparison of equality?

I have noticed that you can't just compare two curves by checking for equality - but I don't understand why - there's no fundamental reason that curves cannot be equal (Rhino could for instance implement something like the code that you linked.)

I'm thinking that the reason that you cannot simply compare curves by control points is that the control points can have different weights - is that the only reason?

Likewise, if you're not supposed to compare points with equality, then why is it implemented? If the issue is about tolerances, Rhino could use the default model tolerance - as you are in your code.

EpsilonEquals will compare any float, point, curve, surface ... by checking its parameters. If one of its parameters (in case of curve: control points, knots, weights...) is larger than supplied tolerance, it means these two curves are not the same (similar).
It essentially does what Rhino's "SelDup" command does, with an exception of being able to include tolerance (actually "SelDup" does include tolerance too, but not the one from Rhino's document, but much smaller one).
The limitation of this is that, like Rhino's "SelDup" command, it will identify duplicates, only if they are stacked on top of each other. If you have duplicate curves, moved on different places in your Rhino workplace, it will not find them.

And yes, your curve, might have different weights for particular control point.
So if you are looking for removal of duplicate curves, stacked one on top of each other, similarBool = crv1.EpsilonEquals(crv2, tol) will do the job for you. If you want to consider duplicate curves, moved somewhere else, rotated, mirrored, or simply stack on top of original one, but with flipped direction, then use the checking of curvature and tangent vectors method.

On why is equality for points implemented: I think this is question for Rhino's developers. But as it was pointed out by one them in the upper link, they suggest always using the tolerance, when checking for equality of anything which involves float point numbers.

For so many years have I suffered the way Rhino refuses to recognize my often hundreds of duplicate curves, since they vary in mere formally assigned direction and often thus detailed control point layout, yet they completely overlap from start to end!

This is also true for surfaces I'd like to delete both copies of as a workaround for typically failed Rhino Boolean unions, where really I want to delete both of each pair that are visually and thus practically coincident and thus bloody well "identical" in 3D space.

Rhino is mathematically way too formal in its behavior in the hands of creative folk, including architecture students who can't finish their projects since Boolean unions refuse to work where any child can see the coincident surfaces between hundreds of parts needing to be to be removed match up exactly.

RSS

About

Translate

Search

Videos

  • Add Videos
  • View All

© 2024   Created by Scott Davidson.   Powered by

Badges  |  Report an Issue  |  Terms of Service