1
$\begingroup$

I generated a bunch of points using mathutils.geometry.interpolate_bezier() but noticed the points are not uniformly distributed on the curve. Please see attached screenshot.

I think it has to do with the interpolation function processing each segment individually which can be dense or sparse depending on how stretched the segment is.

Is there is a better way to interpolate bezier curve and obtain a list of uniformly distributed points?

Thanks! enter image description here

$\endgroup$
  • 1
    $\begingroup$ Related blender.stackexchange.com/questions/47359/… $\endgroup$ – Duarte Farrajota Ramos Oct 30 '17 at 2:28
  • $\begingroup$ This may help : a primer on Bézier curves $\endgroup$ – dr. Sybren Oct 30 '17 at 13:48
  • 1
    $\begingroup$ @John, Bezier curves are evaluated on a non space based paramter (sometiems called 't'). You can think of it as time, and moving along the curve at different speeds. They way I work around this is that I evaluate the enture curve at small t steps, then re-evaluate/interpolate my points to space them evenly along the evaluated curve. $\endgroup$ – patmo141 Feb 25 '18 at 16:10
  • $\begingroup$ github.com/patmo141/odc_public/blob/… $\endgroup$ – patmo141 Feb 25 '18 at 16:11
  • $\begingroup$ @patmo141 Clever. But I end up converting to mesh and subdividing it to generate enough vertices. I thought that is what you did in your code too. Anyways Thanks $\endgroup$ – John Mar 3 '18 at 6:27
4
$\begingroup$

Use offset factor of follow path constraint.


Use the offset factor of follow curve constraint.

Test script, select the curve in object mode and run script.

import bpy
context = bpy.context
scene = context.scene
curve_obj = context.object
spline = curve_obj.data.splines[0]
bpy.ops.mesh.primitive_ico_sphere_add(size=0.05, location=(0, 0, 0))
sphere = context.object
fp = sphere.constraints.new(type='FOLLOW_PATH')
fp.target = curve_obj
fp.use_fixed_location = True

res = len(spline.bezier_points)

spheres = [sphere]
o = 0 if spline.use_cyclic_u else 1
r = spline.resolution_u + 1
pts = (res + o) * r
for i in range(1, pts + o):
    s = sphere.copy()
    sc = s.constraints[0]
    sc.offset_factor = i / pts
    scene.objects.link(s)
    spheres.append(s)

To remove the constraints, and keep their constraint location

# remove constraints
scene.update()
for s in spheres:
    sc = s.constraints[0]
    s.location = s.matrix_world.translation
    s.constraints.remove(sc)
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.