# bug #43452: why splitting a curve is so difficult? (it isn't!)

 Submitted by: gianluca de santis Submitted on: Tue 21 Oct 2014 02:14:41 PM UTC Category: Plugins Severity: 1 - Wish Item Group: Feature request Status: In Progress Privacy: Public Assigned to: None Open/Closed: Open

You are not logged in

## Discussion

Thu 30 Oct 2014 08:46:22 AM UTC, comment #6:

In commit 8d2b00a06af31afaac35e229a32845540050b3ca
example CurveSplit.py a Bezier can be split at values of parameter t. That's good, but how to know what is what value of t which corresponds to a curvilinear distance if there is not a .atLength() method defined  for Bezier?

Tue 28 Oct 2014 10:30:34 PM UTC, comment #5:

The normalized is True is a erroneous indeed. Added a warning in 92e1faf. Probably we will remove the option.

The Curve.splitAtLength returning a PolyLine is just conceptually wrong. It should split the Curve, returning a list of Curves.
If the user is happy with an approximation, he can already approximate first and then split.

We can implement a curve.atLength method returning approximate values for the split parameter values, but the splitting should still return Curves. Therefore, we need a Curve.splitAt. Then splitAtLength can become general.

There is a simple solution for curve.splitAt if there are no more than two splitting points on any curve segment (based on the deCasteljou function from the nurbs module). I think I will add it with the current limitation, until we have something more general.

Benedict Verhegghe <bverheg>
Tue 28 Oct 2014 07:51:21 PM UTC, comment #4:

1) ok relative length only
2) I do not agree with limitation to Polyline because of one reason: in order to compute the 'exact' length on a generic curve there are equations/integrals which, if I remember well, need to be solved numerically because do not have analytical solution:
the relation between the curve parameter 't' and the curvilinear distance L has not an analytical solution.
So solving numerically the equation or approximating the polyline with an arbitrary number of points in my opinion is the same.
That's why I would generalize to Curve.splitAtLength and expose the 'npre' parameter to the user to control the accuracy. Later, the user could choose to use either the 'npre' or, when implemented, to use the numerical integration.
3) in commit e0834fa I also showed a BUG in pointsAt(t=T,normalized=True) which returned points at a WRONG relative length. Please run the attached example to check the BUG.

Tue 28 Oct 2014 07:27:24 PM UTC, comment #3:

PolyLine.splitAtLength is in commit 2fc9fa6.
For other curves, the method might be added later. after implementing exact length computation.

Benedict Verhegghe <bverheg>
Tue 28 Oct 2014 04:55:05 PM UTC, comment #2:

a draft of splitAtLength(L) has been committed.

Tue 21 Oct 2014 03:41:29 PM UTC, comment #1:

Curves are described internally in function of a scalar parameter t. This t is used in many basic function, so you should now about t if you regularly use curves.

The atLength method provides the parameter values at given curvee length. Thus if you want to split at lengths L you can just write

C.splitAt(C.atLength(L))

We could add a method splitAtLength(L) executing this, but that will just save you 6 characters. So I never felt the need. The above gives more feeling about what you are really doing. But I do not object to adding it. If you want the relative feature however, that should be added directly to the atLength() methods!

Now concerning your example: if you approximate a curve with a 100 segment PolyLine, the parameter t will run from 0 to 100.
Thus you could easily split your curve with

Cparts = CP.splitAt([20,50,70])

Benedict Verhegghe <bverheg>
Tue 21 Oct 2014 02:14:41 PM UTC, original submission:

Dear pyFormex developers,

I just updated pyformex to version 1.0.0-a6.

I needed to split a curve C in 4 parts at relative curvilinear positions (20%, 50%, 70%).

It seems that the way now is:

T=array( [0.20,0.50,0.70] ) # relative curvilinear positions
CP = C.approx(nseg=100) # convert curve to polyline
Cparts = CP.splitAt(t=CP.atLength(T)) # list of 4 polylines

This is a basic functionality but to use it I needed to convert my distances into a parameter t (what it is that?) and use t to split the polyline.

A user would be more familiar with the 'position' or 'relative position' or 'distance from the start' rather than the parameter t.

Maybe this functionality could become a friendly general method for all curves like

def splitAtDistance(curve, distance, relative=True)
...
return listOFpolylines

This would split a curve at N absolute (0 to total length) or relative (0 to 1) positions at specified distances from the start and return N+1 polylines.

What do you think?
Gianluca

## Attached Files

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach Files:

Comment:

Attached Files

## Dependencies

Depends on the following items: None found

Items that depend on this one: None found

Carbon-Copy List
• -email is unavailable- added by bverheg (Posted a comment)
•

Do you think this task is very important?
This task has 0 encouragements so far.

Only logged-in users can vote.