Grasshopper

algorithmic modeling for Rhino

I have a curve as a boundary, many circles will be generated inside it.

 I am looking for a method to detect if any circle intersect with the curve. Also If one circle outside of boundary, it need to be trimmed.

What two methods I can call?

Views: 2261

Replies to This Discussion

In the end, what are you trying to do here, because if the end result is to make a planar surface out of all of these curves, then you have quite a far way to go in order to get something useable. Yes you will need to deal with all of the curves that intersect the boundry curve, but you will also need to sort through all of the circles inside because the planar surface algorithm won't sort those out for you. The good news is that because you are using circles and linear segments, you can use "pure" geometry equations for some of these intersections instead of relying on NURBS curve "physical" intersections. In the end this means faster and also "more" reliable intersections (especially with the circles).

Method 1: Dealing with everything as a phyisical curve...
First things first, i guess the "easiest" way to do this would be to translate everything into an OnCurve derived class, and then use the IntersectCurve method to find the intersections. You will need to sort through the resulting ArrayON_XEVENT to find the parameter of each intersection. There should always be 2 intersections, and you're always going to be interested in the intersections of the circle not the boundry curve.

To trim the curves, you'll want to use the Split method along with one of the parameters on the curve that you retrieved from the intersection. The only issue is that the split method gets a bit complicated when using it on closed curves. You could either split at both parameters that you retrieved from the intersection results, then sort through the 3 resulting curves to join the two that you need. Or move the start point of the circle to where one of the intersection points happened, translate the other intersection point to the new curve parameter (ie the parameter will be a different number, but it will be physically in the same place), then split with that new curve parameter.

Method 2: Try and work with the circles as circles

Because you can tell if a circle intersects something by seing if the distance to its center point is less than the radius of the circle, this might be a quicker way to go. If you have the boundry curve as an OnCurve derived class, then you can use the GetClosestPoint method and use all of the center points for each of the circles. The nice thing is that after the 3Dpoint in, and the parameter on the curve that you'll get out, you have the option of supplying a maximum distance. If you do supply that value (use the radius of the circles), then you'll only get a result when the distance is less than or equal to that value. In which case there will be an intersection.

To go even further, you can treat the segments of the boundry curve each as a line, and find the closest point/distance to that. That's maybe more complex than your looking to go, but speed wise, it might just be worth it. Take a look at the following link for more code/discussion on the subject.
http://www.codeguru.com/forum/showthread.php?t=194400

Part 2: Circle-Circle intersections
If you're going to want to make a planar surface out of those circes and the boundry curve, then you'll need to resolve all of the intersections that you have there. Again this is probably something that would be best taken care of by doing some distance tests between the center points of all the circles and seeing if that distance is less than the radius your using. After you've found circles that intersect, you can be try intersecting the curves using the same method mentioned above, or even manually generating the intersection with some trig, but ultimately creating a final result might take a bit of work, especially where you have more than two circles intersecting. The "lazy" way out of this is what's used by the curve boolean command, which is to take each individual curve, make a planar surface from that individual curve, and use standard Rhino booleans to get the result. Luckily you're looking for the union of all those areas, which will be the easiest to create and deal with. After you create the planar surface of each one (RhUtil.RhinoMakePlanarBreps), you can use either RhUtil.RhinoBooleanUnion or the more specialized version, RhUtil.RhPlanarRegionUnion. Note that RhPlanarRegionUnion only takes 2 breps at a time and needs the plane of the intersection.
Damien, thx for such thorough hints.

I guess I will go with OP2, but OP1 also attracts me.

"translate everything into an OnCurve derived class, and then use the IntersectCurve method to find the intersections. " It sounds logic for me to try but I didn't find how to do this yet.
There are two unofficial "groups" of curve classes. The first are curve primitive classes, such as OnLine, OnCircle, OnArc, which are minimal representations of those kinds of curves. The other "group" derives from OnCurve. What that means is that they have inherited their behavior from the OnCurve class. The OnCurve class is actually an abstract class which means that you can't create an OnCurve directly. Instead OnCurve just lays out a bunch of functions that must be implemented for classes that derive from it. These functions allow the curves to be displayed in the Rhino viewport as well as allow for physical intersections to be performed.

In this case, getting an OnCurve derived form of a circle is pretty easy, since there is the OnArcCurve class which will take an OnCircle as an argument in one of its constructors. In general, a good way it so use the GetNurbsForm method that is exposed for most non-OnCurve classes, which returns an OnNurbsCurve.
I felt I lost. I tried several hours to convert a circle into an onCurve object but no success so far.

Here is the code I am testing so far. But it isn't right:

Private Sub RunScript(ByVal x As OnCircle, ByVal y As OnLine, ByRef A As Object)
Dim circleMy As New OnArcCurve

'convert x into an onCurve Object
circleMy.GetNurbForm(x)

End Sub

Will look for answer on another thread:
http://www.grasshopper3d.com/forum/topics/vbnet-oncurve?commentId=2...

What did I miss?

Dim circleMy As New OnArcCurve(x)

--
David Rutten
david@mcneel.com
Poprad, Slovakia
Hi, David:

Thanks. I still have some problems to test the intersection in line and circle. So here i am trying to test a two lines intersection instead
, but still runs into a problem:
here is the code:

Private Sub RunScript(ByVal x As OnLine, ByVal y As OnLine, ByRef A As Object)

Dim line01 As New OnLine(x)
Dim line02 As New OnLine(y)
Dim num01 As Double
Dim num02 As Double
Dim tolerance01 As Double
Dim bool01 As int32

'find intersect point between two lines
print(OnUtil.ON_IntersectLineLine(line01, line02, num01, num02, tolerance01, bool01))

End Sub

Also I attached a screen shot. You can see those two lines are seperaed, but the print result is 'true'. Do you know why? I checked Rhino 4.NET SDK, it says this method return a boolean value.

Hi cmrhm,

since x and y are already OnLines, you don't technically need to duplicate them.


Dim t0 As Double
Dim t1 As Double

'Intersect finite segments...
If (Not OnUtil.ON_IntersectLineLine(x, y, t0, t1, 1e-6, True)) Then Return

A = x.PointAt(t0)


ON_IntersectLineLine can work on both finite and infinite segments. If you change the final argument in ON_IntersectLineLine from True to False, you'll switch to the infinite line logic.

--
David Rutten
david@mcneel.com
Poprad, Slovakia
Thx, david. It works. Happy to see you introduced the method pointat().

I began to tackle the issue regarding the intersection between circle and line. The method I use is intersectCurve(). My intent is to find the intersection points. But the result isn't what it is supposed to be. After getting intersection point, I need to trim the curve.

Attachments:
I was trying to use OnUtil.ON_Intersect() method to find the intersection, but got an error which ask for an narrowing conversion.

Pls see the attached.
Attachments:
Hi cmrhm,

I don't understand. Why are you using both OnCurve.IntersectCurve and OnUtil.ON_Intersect?

ON_Intersect won't work because it requires an OnLine and an OnCircle, and you're feeding it an OnCurve and an OnCircle.

--
David Rutten
david@mcneel.com
Poprad, Slovakia
David:

Pls allow me to explain what I understand for abstract class OnCurve. I guess if I don't get this concept, I won't be able to do the rest.

"ON_Intersect won't work because it requires an OnLine and an OnCircle, and you're feeding it an OnCurve and an OnCircle."

These was due to the confusion I was with the abstract class OnCurve initially. Based on my reading, I guess we shouldn't declare an instance from OnCurve, instead, we should instantiate an object inherited from OnCurve like OnLine. Then we could use all the beautiful methods under OnCurve.

The idea for creating abstract class is neat. By doing that, you don't need to write the same methods for all the similar classes like OnLine, OnCircle. You write a bunch of methods under OnCurve. Then for example, the objects by Online class could be able to access all of those methods.

Do I understand it right?

Here is the graph helps me:

OnCurve(abstract class)
.OnLineCurve
.OnPolylineCurve
.OnNurbsCurve
.OnCurveSurface
.OnCurveProxy
David:

The attached you will find my code by using On_Intersect(). Got improved, however, the result doesn't match with what SDK said.

In the rhino drawing, u see the circle didn't intersect with the line. But the return value from method On_Intersect is 1. Based on SDK, it should be 0. Did I do sth wrong?

VBNET_intersectCurve.3dmVBNET_intersectCurve.ghx

RSS

About

Translate

Search

Videos

  • Add Videos
  • View All

© 2024   Created by Scott Davidson.   Powered by

Badges  |  Report an Issue  |  Terms of Service