11

I have a 3D parametric curve defined as P(t) = [x(t), y(t), z(t)].

I'm looking for a function to reparametrize this curve in terms of arc-length. I'm using OpenSCAD, which is a declarative language with no variables (constants only), so the solution needs to work recursively (and with no variables aside from global constants and function arguments).

More precisely, I need to write a function Q(s) that gives the point on P that is (approximately) distance s along the arc from the point where t=0. I already have functions for numeric integration and derivation that can be incorporated into the answer.

Any suggestions would be greatly appreciated!

p.s It's not possible to pass functions as a parameter in OpenSCAD, I usually get around this by just using global declarations.

Jeremiah Rose
  • 3,865
  • 4
  • 27
  • 31
  • 1
    Sorry if the question comes across as too demanding, I'm working on the problem too so if I come up with a solution will definitely post it here xx – Jeremiah Rose Mar 16 '19 at 06:21
  • How do you call your calculus functions? What limitations do they have? – wizzwizz4 Mar 16 '19 at 13:44
  • You can't pass functions as arguments in OpenSCAD so I just have a separate calculus function for each derivative or integral. For example if we want the derivative for f(x) at the point x I would have a function df(x, dx) = (f(x+dx) - f(x-dx))/(2*dx). Pretty basic but it works – Jeremiah Rose Mar 17 '19 at 10:57
  • 1
    Ah, I see. Yeah, that makes sense. Hence "approximation". – wizzwizz4 Mar 17 '19 at 13:49

1 Answers1

2

The length of an arc sigma between parameter values t=0 and t=T can be computed by solving the following integral:

sigma(T) = Integral[ sqrt[ x'(t)^2 + y'(t)^2 + z'(t)^2 ],{t,0,T}]

If you want to parametrize your curve with the arc-length, you have to invert this formula. This is unfortunately rather difficult from a mathematics point of view. The simplest method is to implement a simple bisection method as a numeric solver. The computation method quickly becomes heavy so reusing previous results is ideal. The secant method is also useful as the derivative of sigma(t) is already known and equals

sigma'(t) = sqrt[ x'(t)^2 + y'(t)^2 + z'(t)^2]

Maybe not really the most helpful answer, but I hope it gives you some ideas. I cannot help you with the OpenSCad implementation.

kvantour
  • 25,269
  • 4
  • 47
  • 72
  • Thanks kvantour. My current approach is to try and calculate successive equidistant points along the curve using a modified binary search. I'll post the OpenSCAD up here if it works. This would be so much easier in Python, or Javascript! – Jeremiah Rose Mar 20 '19 at 07:57
  • @JeremiahRose would be nice to see your OpenSCAD code in your original question. However, if you want points at a distance L from one another, you can always compute sigma(T) between (0,t1) -> L, and then (t1,t2) -> L and then (t2, t3) -> L ... but this will accumulate errors. It is better to use (0,t1) -> L, (0,t2) -> 2L, (0,t3) ->3L, ... – kvantour Mar 20 '19 at 09:36
  • I've given up on this problem because OpenSCAD also has no debugging facilities, which made finding problems with infinite recursion extremely frustrating (constant closing of the app with task manager and restarting it). I've moved the whole project over to Ruby scripts in Sketchup. – Jeremiah Rose Mar 24 '19 at 23:27