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!


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
| improve this answer | |
  • $\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 at 9:29

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.