Given large curves (red) and smaller curves (blue) I want to return only blue curves that overlap red curves by more than 99% of its area. Blue curves that have more than 1% area outside of red curves are ignored. My script utilizes Rhino.Geometry.Curve.CreateBooleanDifference() to find if the excess area is more than 1%. My question is: how do you get the area of a closed planar curve via rhinocommon? And/or is there a better way of approaching this?
import Rhino.Geometry as rg
redclosed=rg.Curve.JoinCurves(red)[0]
bluelist=[]
arealist=[]
for i in blue:
temp1=rg.Curve.CreateBooleanDifference(i,redclosed)
if len(temp1)==0:
arealist.append(0)
else:
area=0
for j in temp1:
area+=#get area of j
arealist.append(area)
if arealist[-1]/ #area of i<.01:
bluelist.append(i)
a=bluelist
b=arealist
Kind of a side question. In grasshopper you can reparameterize a curve so that the t values are between 0 and 1. Is there a way to do this in Rhinocommon?
Why do you need to do this? If not done correctly, Reparameterizing objects can lead to issues later on. Check the Rhino help file for the Reparameterize command for more details.
If I have two reparameterized curves, I know that crv1.PointAt(0) will be at the start, crv1.PointAt(.5) will be in the middle, and crv.PointAt(1) will be at the end. And those t values will do the same for crv2. Currently I have to Rhino.Geometry.Curve.DivideByCount() for each curve which returns numbers that do not apply to other curves because of their different lengths. Is there a better way to do this?
I always reparameterize in grasshopper because it just seems cleaner.
rc, t = curve.NormalizedLengthParameter(0.0)
if rc:
start_point = curve.PointAt(t)
rc, t = curve.NormalizedLengthParameter(0.5)
if rc:
mid_point = curve.PointAt(t)
rc, t = curve.NormalizedLengthParameter(1.0)
if rc:
end_point = curve.PointAt(t)
Another side question: in the case where a method will return different sets of data, how do I select which set I get?
Rhino.Geometry.Curve.DivideByCount() will either return floats and points or just floats. How do I know which one will be the output. Only the “just floats” version seems to work for me.
Calling overloaded function in IronPython can be painful. Calling overloaded functions with an argument that is passed by reference is even more so.
The overloaded version of DivideCurveCount is declared in C# line this:
public double[] DivideByCount(int segmentCount, bool includeEnds, out Point3d[] points);
The out keyword causes arguments to be passed by reference.
The Python language passes all arguments by-value. There is no syntax to indicate that an argument should be passed by-reference like there is in .NET languages like C# via the ref and out keywords.
Anyway, with some CLR voo-doo and a .NET class named StrongBox, you can get there.