以前のコードが汎用性に欠けるというか使いにくかったのでもう一度書き直した。
import bpy import math import mathutils
#################################################################### #################################################################### #################################################################### #################################################################### # @brief 任意軸回転 # @sa https://www.study.suzulang.com/bpy/bpy-arbitrary-axis-rotation # @param [in,out] obj 回転するオブジェクト # @param [in] axis 回転軸 # @param [in] radian 回転角をラジアンで指定 # @return なし def rotate_object(obj,axis,radian): rot_mat= mathutils.Matrix.Rotation( radian, 4, axis ) # decompose world_matrix's components, and from them assemble 4x4 matrices orig_loc, orig_rot, orig_scale = obj.matrix_world.decompose() # orig_loc_mat = mathutils.Matrix.Translation(orig_loc) orig_rot_mat = orig_rot.to_matrix().to_4x4() orig_scale_mat = (mathutils.Matrix.Scale(orig_scale[0],4,(1,0,0)) @ mathutils.Matrix.Scale(orig_scale[1],4,(0,1,0)) @ mathutils.Matrix.Scale(orig_scale[2],4,(0,0,1))) # # assemble the new matrix obj.matrix_world = orig_loc_mat @ rot_mat @ orig_rot_mat @ orig_scale_mat
#################################################################### #################################################################### #################################################################### #################################################################### #################################################################### # @brief 指定した位置に矢印を作成 # @param [in] tail 矢印の根本 # @param [in] head 矢印の頭 # @param [in] body_radius 矢印根元の半径 # @return 作成した矢印のオブジェクト def create_arrow(tail,head,body_radius): ########################################### ########################################### # tail->head の長さと方向を計算 avec = head - tail aveclen = avec.length avec.normalize() ########################################### ########################################### # 回転軸と回転量 zvec = mathutils.Vector([ 0.0 , 0.0 , 1.0]) zvec.normalize() rotvec = mathutils.Vector.cross(zvec,avec) rotvec.normalize() rotang = math.acos(mathutils.Vector.dot(zvec,avec) ) ########################################### ########################################### # 各パラメータ計算 # bodyとheadの長さの比率 head_ratio = 0.3 # 頭部長さ変更 head_length = aveclen * head_ratio # 頭部が長くなりすぎないように調整 if head_length > 0.3*4: head_length = 0.3*4 body_length = aveclen - head_length # 矢印の頭部分の付け根の大きさ(本体に対する倍率) head_root_ratio = 2.0 ########################################### ########################################### # サークル追加 # 半径は body_radius bpy.ops.mesh.primitive_circle_add( location=tail, radius=body_radius ) myarrow = bpy.context.object # 作成したサークルを回転して目標へ向ける rotate_object(myarrow,rotvec,rotang) ####################### # サークルを面にする bpy.ops.object.mode_set(mode='EDIT') bpy.ops.mesh.fill() ####################### # step 1 - 押し出し # 押し出し量は 矢印全体の長さ×比率 bpy.ops.mesh.extrude_region_move( TRANSFORM_OT_translate={"value":avec*body_length } ) ####################### # step 2 -| 矢印頭部部分付け根拡大 bpy.ops.mesh.extrude_region_move( TRANSFORM_OT_translate={"value":(0,0,0)} ) bpy.ops.transform.resize( value=( head_root_ratio, head_root_ratio, head_root_ratio) ) ####################### # step 3 -|= 矢印頭部部分押し出し bpy.ops.mesh.extrude_region_move( TRANSFORM_OT_translate={"value":avec*head_length} ) ####################### # step 4 -|> 矢印を閉じる bpy.ops.transform.resize(value=(0,0,0) ) bpy.ops.mesh.remove_doubles() bpy.ops.object.mode_set(mode='OBJECT') return myarrow
################################ #実行例 t = mathutils.Vector((1,2,1))#始点 h = mathutils.Vector((-1,2,3))#先端 arrow = create_arrow(t,h,0.1) arrow.name = "my-arrow" print (arrow)