# An array of 3D arrows (python in Blender)

I am new to Blender and I want to create an array of 3D arrows; the array itself is 2*2 (constant space between each object) but the arrows are 3D.

I hope to write a python code for it but I don't know where to start. There is a code in the following link for a single 3D arrow, but I'm afraid I cannot use it.

Blender Orient an object (displaying Vector Arrows)

• This isn’t very clear. Can you draw what you were trying to do? I mean, if all you want is an array of arrows, you can just use the array modifier and get 400 arrows all pointing in the same direction. Also, I know you’re trying to help, but saying “I am new to Blender“ doesn’t really specify anything. Some ideas of being “new to blender“ means that they haven’t used it for more than a year. May 14 at 22:05
• Thanks for the reply. Sorry for not being clear. I started working with Blender 2-3 months ago (not full-time though, occasionally I can say). 99% of the time, I draw objects without using python; just recently I started to use python. I can definitely draw what I am hoping to do, but for some reasons I want to use scripting because it adds flexibility for future use as well as if I want to extend my draw, it would be pretty easy. Regarding this structure, although I said array, actually I am going to draw a hexagonal/honeycomb lattice. But to start, array is an easier place to start. Thanks
– Reza
May 14 at 22:19
• I would try geometry nodes before scripting in this case. May 14 at 22:43
• So… is the question[s]: “how to create an arrow mesh (if so what are the specs of the arrow); how to duplicate linked an object in desired positions, and (not about blender) how to generate a honeycomb lattice of points, in Python” May 15 at 4:19
• Hi, sorry for the delay. yes, the question is how to create an arrow (mesh) with python. Thanks
– Reza
May 16 at 14:53

Here's something I wrote that I think you might find useful. v0, v1, and v2 are three corners of a square and I used nested for loops to create an array of arrows. To create the arrows themselves, I wrote a mesh-from-scratch function "createArrow". Let me know if I need to fix anything.

import bpy
from math import *
from mathutils import Vector

verts = []
edges = []
faces = []
#append tube verticies 0 thru (tubeAcross x tubeAround - 1)
for i in range(tubeAcross):
v1 = tubeLength * (i / (tubeAcross - 1)) #- length/2
for j in range(tubeAround):
angle = 2 * pi * j / tubeAround

verts.append([v1, v2, v3])

index1 = tubeAround * i + j
index2 = tubeAround * i + j + 1
if index2 == (i + 1) * tubeAround:
index2 = i * tubeAround
edge = [index1, index2]
edges.append(edge)

#append cone verts (tubeAcross x tubeAround) thru (tubeAcross x tubeAround + coneAround + 1) (exctra 1 for the tip)
angle = 2 * pi * i / headAround
v1 = tubeLength
verts.append([v1, v2, v3])

verts.append([arrowLength, 0, 0])

#append tube faces:
# for i in range of number of faces (added 1 for the circle face)
for i in range(tubeAround * (tubeAcross - 1) + 1):
face = []
if i == 0:
# make face out of first slicesAround edges:
for j in range(tubeAround):
face.append(edges[j][0])
else:
face = [edges[i - 1][0], edges[i - 1][1], edges[i - 1 + tubeAround][1], edges[i - 1 + tubeAround][0]]

faces.append(face)

#append face for back of cone:
face = []
face.append(tubeAround*tubeAcross + i)
faces.append(face)

#append cone faces:
index1 = tubeAcross * tubeAround  + i
index2 = tubeAcross * tubeAround + i + 1
index3 = tubeAcross * tubeAround + headAround

if index2 == index3:

face = [index1, index2, index3]
faces.append(face)

mesh = bpy.data.meshes.new("Arrow")
arrow = bpy.data.objects.new("Arrow", mesh)
#col = bpy.data.collections.get("Collection")
mesh.from_pydata(verts, [], faces)

# ---------------MAIN--------------------

#creation variables
tubeAcross = 2
tubeAround = 50

arrows = bpy.data.collections.new("Arrows")

numAcross = 5
v0 = Vector([-1, 1, 0])
v1 = Vector([-1, -1, 0])
v2 = Vector([1, 1, 0])

for i in range(numAcross):
for j in range(numAcross):

tip = v0 + (i/(numAcross - 1)) * (v2 - v0) + (j/(numAcross - 1)) * (v1 - v0)

arrowLength = tip.magnitude

arrow = arrows.objects[j + i*numAcross]

for f in arrow.data.polygons:
f.use_smooth = True

arrow.data.use_auto_smooth = 1

x = tip.x
y = tip.y
z = tip.z
mag = sqrt(x**2 + y**2)

if x == 0 and y >= 0:
theta = pi/2
elif x == 0 and y < 0:
theta = -pi/2

elif x < 0:
theta = pi + atan(y/x)
else:
theta = atan(y/x)

if mag == 0 and z >= 0:
beta = pi/2
elif mag == 0 and z < 0:
beta = -pi/2
elif mag < 0:
beta = pi + atan(z/mag)
else:
beta = atan(z/mag)

arrow.rotation_euler = (0, beta, theta)