Subdivision of curves with max spacing

Hi there! I have a problem where I want to create a beams orthogonal to two curves where the maximum allowed space between the beams can be 2 meters. So on a straight track the spacing is 2 meters, but on sections that turns, either concave or convex, spacing should use either the outside curve or the inside curve as reference for the spacing between the beams. All the time keeping track of the already created beams. I figure this can be solved with some clever iterative Python or Designscript magic, but it’s way past my skill level. Anyone wants to just point in a direction as to where to start such a thing? Or maybe just the overarching logic of an iterative script like that? Would be a great training exercise! :slight_smile:

2 Likes

I’m assuming you are starting with two polycurves here (ie: the left polycurve and the right polycurve).

  1. Polycurve.Curves to get two lists of curves.
  2. List.Transpose to get matching depth lists of curves.
  3. Curve.Length to get the length of each curve.
  4. List.MaximumItem to get the longer item.
  5. List.IndexOf to get the index of the two curves
  6. List.GetItemAtIndex to get the actual curve element.
  7. Divide the curves up accordingly based on maximum length, getting the points acordingly.
  8. Go back to the paired list of curves in step 2 and remove the longer curves (step 6) you’re left with only the smaller elements.
  9. Project the points (step 7) onto the lines.
  10. Connect the dots (step 7 and step 9) with lines to host the beams.
  11. Verify the start points (step 7) are less than the allowable spacing apart using a pair of list chop nodes and a Geometry.DistanceTo node.
  12. Verify the end points are all less than the allowable spacing apart using a pair of list.chop nodes and a Geometry.DistanceTo node.
  13. Create a model line between any consecutive start/end points which are over the maximum allowable so you an manually review any errors (yes the humans are still on the hook when the algorithms don’t work out :smile:).
1 Like

Hi @jostein_olsen

Here is one of the possible way…


@jostein_olsen Hope this works for you …
Needs improvement, in the definition below the number of points/beams is fixed at 28
OrthBms.dyn (7.9 KB)

def br1(c1,c2,p1,s1)
{
r1 = c1.ParameterAtPoint(p1);
p2 = c2.ClosestPointTo(p1);
r2 = c2.ParameterAtPoint(p2);
p3 = c2.PointAtChordLength(s1,r2,true);
p4 = c1.ClosestPointTo(p3);
d1 = p1.DistanceTo(p4);
p5 = d1<=s1?p4:c1.PointAtChordLength(s1,r1,true);
return = p5;
};

def br2(c1,c2,p1,s1)
{
	return = [Imperative]
	{
		n = 0;
		p3 = {};
		while (n<28)
		{
			p3[n] = br1(c1,c2,p1,s1);
			p1 = p3[n];
			n = n + 1;

		}
		return = p3;
	}
};

max = 2000;
pt1 = br2(cr1,cr2,cr1.StartPoint,max);
pt2 = cr2.ClosestPointTo(pt1);
ln1 = Line.ByStartPointEndPoint(pt1,pt2);
4 Likes

Holy c***, @Vikram_Subbaiah… i’ll check tomorrow but you have already done the testing and it works like a charm I can see. I’ll post the results tomorrow hopefully and show you the rest of the graph: here is the results with a more manual approach: https://twitter.com/jos_ols/status/922460340515991552

1 Like

Hmm, seems like I can’t get it to work…


Could it have something to do with the assigning of the newly created point to the p1 parameter in the imperative part?

Unlikely. I’ll post a slightly improved version shortly.
Meanwhile, could you to share the input curves you’re testing this with?

Its actually a Solid in a family, and I’ve been using Isocurves to drive the geometry:

Improved Version of the above definition …

OrthBms.dyn (13.8 KB)

def br1(c1,c2,p1,s1)
{
	r1 = c1.ParameterAtPoint(p1);
	p2 = c2.ClosestPointTo(p1);
	r2 = c2.ParameterAtPoint(p2);
	p3 = c2.PointAtChordLength(s1,r2,true);
	p4 = c1.ClosestPointTo(p3);
	d1 = p1.DistanceTo(p4);
	p5 = d1<=s1?p4:c1.PointAtChordLength(s1,r1,true);
	return = p5;
};

def br2(c1,c2,s1)
{
	return = [Imperative]
	{
		n = 0;
		q = Math.Ceiling(c1.Length/s1);
		p1 = c1.StartPoint;
		p3 = {};
		while (n <= q)
		{
			p3[n] = br1(c1,c2,p1,s1);
			p1 = p3[n];
			n = n + 1;

		}
		return = p3;
	}
};

max = 4000;
pt1 = br2(cr1,cr2,max);
pt2 = cr2.ClosestPointTo(pt1);
ln1 = Line.ByStartPointEndPoint(pt1,pt2);

Works on reversing the direction of one of the curves.
Path.dyn (13.5 KB)

Optionally, as @jacob.small suggested, selecting the longest sides for division by max length can possibly lead to usable results:

Interesting code! Thanks! Still breaking it down though to understand the process.:male_detective:

I’m wondering, what approach would work best for the subdivision of a surface between the two curves based on maximum area.

Hi, I believe I got to finally understand how the code works. On manipulation though, the code was not yielding consistent results visually particularly on decreasing the max value to around 1000.
:no_mouth:

I’m guessing this is because the value of q at def: br2 ran out too quickly at the final curve and thus the iteration didn’t fully subdivide the curves to the end.

I’ve tried to adjust the while loop of br2 to run on the basis of the parameter at point value but my result is always a list of one point. What could I be missing?

You’re right. Modified the code to check if the parameter at point is less than 1, instead.
Should work better now.
Path-20190217.dyn (15.2 KB)

6 Likes

Solved by @Vikram_Subbaiah

:sunglasses:

1 Like