I have a Python script in which I create a bezier curve. I want to rotate the first and last handle so that it is perpendicular to the normal of a certain face.

Something like this:

enter image description here

I have the face normal calculated like this and the 4x4 rotation matrix:

# Get intersection with objects
hit, loc_hit, norm, face, *_ = scene.ray_cast(context.view_layer, origin, view_vector)
if hit:
    z = Vector((0,0,1))
    rot = z.rotation_difference( norm ).to_matrix().to_4x4()
    return loc_hit, rot

Now I want to use this rotation matrix to rotate the handles, but this doesnt seem to work, they are pointing in complete different direction, here is the code I tried:

bez_points = curve.data.splines[0].bezier_points
point_count = len(bez_points) - 1

# get_start_rotation just returns this:  z.rotation_difference( norm ).to_matrix().to_4x4()

rot_start = curve_shape.get_start_point() @ curve_shape.get_start_rotation()
rot_end = curve_shape.get_end_point() @ curve_shape.get_end_rotation()

bez_points[0].co = curve_shape.get_start_point()
bez_points[0].handle_right = rot_start
bez_points[0].handle_left = rot_start

bez_points[point_count].co = curve_shape.get_end_point()
bez_points[point_count].handle_right = rot_end
bez_points[point_count].handle_left = rot_end

Any ideas? Thx in advance!


1 Answer 1


Ok, found a solution: Just adding or subtracting the normal vector to or from the control-point of the curve:

Like before the normal of the face I get from here

hit, loc_hit, norm, face, *_ = scene.ray_cast(context.view_layer, origin, view_vector)

Then I add or subtract it to the control point of the bezier curve:

norm_start = curve_shape.get_normal_start()
norm_end = curve_shape.get_normal_end()

bez_points[0].co = curve_shape.get_start_point()
if norm_start is not None:
    bez_points[0].handle_right = bez_points[0].co + norm_start
    bez_points[0].handle_left = bez_points[0].co - norm_start

bez_points[point_count].co = curve_shape.get_end_point()
if norm_end is not None:
    bez_points[point_count].handle_right = bez_points[point_count].co - norm_end
    bez_points[point_count].handle_left = bez_points[point_count].co + norm_end
  • $\begingroup$ Please add your revised code so that it could be helpful for other users who might run into the same problem. $\endgroup$
    – TLousky
    Jan 14, 2020 at 9:29

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .