I do some simple vector algebra and want to illustrate the vectors and points in Blender. However, there is a disconnect that I would like some outside perspective on to disentangle. Here is the code that shows my issue.
I have a slightly tilted line given by the point P and a direction vector, and I have a point A. I want to calculate the vector projection of the point A onto the line. I want to connect the point A with the projected point with a straight line.
import bpy import numpy as np point_radius = .025 line_rot_x = 0 * np.pi / 180 # 5° rotation around x axis line_rot_y = 0 * np.pi / 180 # 3° rotation around y axis line_len = 1 # in meter line_radius = .01 P_y = 1 P_x = 1 A = np.array([0, 0, 0]) bpy.ops.mesh.primitive_uv_sphere_add(radius=point_radius, location=A) P = np.array([P_x, P_y, 0]) bpy.ops.mesh.primitive_cylinder_add(location=P, scale=(line_radius, line_radius, line_len)) # align the line (more or less, given the rotation) with the z-axis bpy.context.object.delta_rotation_euler = (line_rot_x, line_rot_y, np.pi/2) # set up some helpful math things to make calculation of the planes and vectors easy rotation_matrix = np.dot( np.array([[1, 0, 0], [0, np.cos(line_rot_x), np.sin(line_rot_x)], [0, -np.sin(line_rot_x), np.cos(line_rot_x)]]), np.array([[np.cos(line_rot_y), 0, -np.sin(line_rot_y)], [0, 1, 0],[np.sin(line_rot_y), 0, np.cos(line_rot_y)]])) line_direction_vector = np.dot(rotation_matrix, np.array([0, 0, 1])) # rotate the direction vector of the z-axis print(str("direction vector of the line " + str(line_direction_vector))) A_proj = P + line_direction_vector * np.dot((P-A), line_direction_vector) / np.dot(line_direction_vector, line_direction_vector) print(str("point A, projected on line: " + str(A_proj))) # mark the projected point, and the normal plane in the point bpy.ops.mesh.primitive_uv_sphere_add(radius=point_radius, location=A_proj) bpy.ops.mesh.primitive_plane_add(size=1, location=A_proj) bpy.context.object.delta_rotation_euler = (line_rot_x, line_rot_y, np.pi/2) # connect the A and A_proj bpy.ops.curve.primitive_bezier_curve_add() obj = bpy.context.object obj.data.dimensions = '3D' obj.data.fill_mode = 'FULL' obj.data.bevel_depth = 0.01 obj.data.bevel_resolution = 4 obj.data.splines.bezier_points.co = A_proj obj.data.splines.bezier_points.handle_left_type = 'VECTOR' obj.data.splines.bezier_points.co = A obj.data.splines.bezier_points.handle_left_type = 'VECTOR'
This should work with all kind of As, Ps and direction vectors for the line.
As you can see, Blender's perception of where the
point_coordinate is differing between drawing the sphere and when drawing the connecting line. My math to calculate the vector projection is also off - the globe should be in the plane, and so should the connecting line.
When I subsequently increase just one value of the code, e.g. one of the rotation angles, rerunning the script without cleaning the canvas, the expected result and blenders reality diverge more with each step, and I don't quite understand why.
This is an example of what I expect to happen (thanks to Sam-Hirsch for the vid).
Where did I go off the tracks?