I need to move a bone like these pictures.
There are two long bones,and in edit mode I need to put the small bone's head exactly on the place where two long bones crossed. I tried to use edge snap mode, but it didn't work. Do you know how?
Blender Stack Exchange is a question and answer site for people who use Blender to create 3D graphics, animations, or games. It only takes a minute to sign up.
Sign up to join this communityMost of this work is knowing the coordinates to be moved. However, with the exception of the head and tail, it is rare for two bones to share exactly one point. So instead of the shared point, I decided to find for the closest one to the two bones. The following script will move the 3D cursor to the expected coordinates, then snap the destination bone to the cursor yourself.
import bpy
def closest_point_between_two_lines(va1, vb1, va2, vb2):
from mathutils import Vector, Matrix
va = [va1, va2]
vs = [(vb1 - va1).normalized(), (vb2 - va2).normalized()]
ma = Matrix([
[vs[0] @ vs[0], -vs[1] @ vs[0]],
[vs[0] @ vs[1], -vs[1] @ vs[1]]
])
if not ma.determinant():
raise
vc = Vector([(va[0]-va[1]) @ vs[0],
(va[0]-va[1]) @ vs[1]])
# where, C + A @ R = 0
vr = -1 * ma.inverted() @ vc
vp = [0]*2
for i in range(2):
vp[i] = va[i] + vr[i] * vs[i]
return 0.5 * (vp[0] + vp[1])
obj = bpy.context.object
bones = obj.data.edit_bones
bone1 = bones[0]
bone2 = bones[1]
pos = closest_point_between_two_lines(
bone1.head, bone1.tail,
bone2.head, bone2.tail
)
bpy.context.scene.cursor.location = obj.matrix_world @ pos
I won't go into the details of my function, but you can find something similar with keyword "closest point between two lines".
Sorry, the desired function has already been provided in the mathutils module.
mathutils.geometry.intersect_line_line(lineA_p1, lineA_p2, lineB_p1, lineB_p2)
import mathutils
poss = mathutils.geometry.intersect_line_line(
bone1.head, bone1.tail, bone2.head, bone2.tail
)
pos = (poss[0] + poss[1]) /2
bpy.context.scene.cursor.location = obj.matrix_world @ pos