# Rotate bezier handles with Python to face normal

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:

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


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

• Please add your revised code so that it could be helpful for other users who might run into the same problem. – TLousky Jan 14 at 9:29