Ask Your Question

Evenly space points along a parametric curve?

asked 2011-11-14 14:44:56 -0500

niles gravatar image

updated 2011-11-15 08:34:55 -0500

Are there arc-length parametrization functions hidden somewhere in Sage? I have some 3D parametric curves (smooth) of length L along which I would like to put n dots at regular intervals. What I've been doing so far is using numerical integration to find the arc length parameter, and then using find_root to find the positions of the dots (spaced by arc length L/n).

This is pretty slow, and has the further limitation that I need to specify a region on which find_root should work. If the parametrization is really uneven, it's tough to develop a good initial estimate for where to look.

So, does anyone have other ideas for doing this? Thanks!

UPDATE: Here are some examples -- they're different fibers in the Hopf fibration, and are given by r = (rx,ry,rz)

Example 1:

rx(t) = -0.309*cos(t)*arccos(0.951*cos(-t - 1.57))/(sqrt(-0.904*cos(-t - 1.570)^2 + 1)*pi)
ry(t) = -0.309*sin(t)*arccos(0.951*cos(-t - 1.57))/(sqrt(-0.904*cos(-t - 1.57)^2 + 1)*pi)
rz(t) = 0.951*sin(-t - 1.57)*arccos(0.951*cos(-t - 1.57))/(sqrt(-0.904*cos(-t - 1.57)^2 + 1)*pi)]

Example 2:

rx(t) = -0.707*cos(t)*arccos(0.707*cos(-t - 1.57))/(sqrt(-0.5*cos(-t - 1.57)^2 + 1)*pi)
ry(t) = -0.707*sin(t)*arccos(0.707*cos(-t - 1.57))/(sqrt(-0.5*cos(-t - 1.57)^2 + 1)*pi)
rz(t) = 0.707*sin(-t - 1.57)*arccos(0.707*cos(-t - 1.57))/(sqrt(-0.5*cos(-t - 1.57)^2 + 1)*pi)
edit retag flag offensive close merge delete


Could you give an example of a typical curve that you're considering?

jdc gravatar imagejdc ( 2011-11-15 08:19:32 -0500 )edit

Unless a given curve has special properties (say, an ellipse) I don't know that there is a better way in general. Would it work for your needs if we did it this way but faster?

DSM gravatar imageDSM ( 2011-11-16 00:39:13 -0500 )edit

sure, faster would definitely be good. I tried writing some cython functions myself, but couldn't really get speed improvements.

niles gravatar imageniles ( 2011-11-16 01:09:51 -0500 )edit

1 answer

Sort by ยป oldest newest most voted

answered 2013-04-20 04:03:14 -0500


I used some numerical integration (by hand) and without find_roots. It works quite well and quite fast.

x(t) = 2*cos(t) - cos(2*t)
y(t) = 2*sin(t) - sin(2*t)

dx(t) = x.derivative(t)
dy(t) = y.derivative(t)

arc_length = fast_callable(sqrt(dx(t)**2 + dy(t)**2), vars=(t,), domain=RR)

First I make an approximation of the total length of my curve

total_length = 0.0
for s in xsrange(0,2*pi,0.001):
    total_length += arc_length(s) * 0.001

And then it is possible to store equally spaced points (here 20)

nb_pts = 20
step = total_length / nb_pts
length = 0.
next_pt = step
L = [(x(0),y(0))]
for s in xsrange(0,2*pi,0.001):
    length += arc_length(s) * 0.001
    if length >= next_pt:
        next_pt += step


parametric_plot((x(t),y(t)), (t,0,2*pi)) + point2d(L, color='red', pointsize=20)

image description

edit flag offensive delete link more

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools


Asked: 2011-11-14 14:44:56 -0500

Seen: 560 times

Last updated: Apr 20 '13