# Find out perpendicular vectors of a normal

I want to find out the direction of a certain axis in a normal, for example the Y axis. So for an edge finding the direction would be to subtract the location of its vertices. I want to use that normal direction to move a face along the Y direction of its normal rather than the Z axis. I'm looking for a python solution.

I've figured it out using bm.face[#].calc_tangent_edge(). Although I can't figure out why it goes to X axis then to Y axis when selecting faces in other parts of the mesh. I also need a 90° equivalent of this tangent to able to use this on a gridify script.

import bpy
import bmesh

obj = bpy.context.edit_object
me = obj.data
bm = bmesh.from_edit_mesh(me)
f = bm.select_history.active
n = f.calc_tangent_edge()
vec = 0.1 * n

for v in f.verts:
v.co += vec

bmesh.update_edit_mesh(me, True)


## Moving across a plane, horizontally

import bpy
import bmesh

threshold = 0.0001

obj = bpy.context.edit_object
me = obj.data
bm = bmesh.from_edit_mesh(me)
f = bm.select_history.active
normal = f.normal
tangent1 = f.calc_tangent_edge()
tangent2 = normal.cross(tangent1)
if abs(tangent1.z) < threshold:
vec = tangent1  # this tangent already is horizontal
elif abs(tangent2.z) < threshold:
vec = tangent2
else:
ratio = tangent1.z / tangent2.z
vec = tangent1 - tangent2*ratio

vec.z = 0  # it's close to 0 but let's just round it exactly to 0
vec.normalize()
vec *= .1

for v in f.verts:
v.co += vec

bmesh.update_edit_mesh(me, True)

• " I can't figure out why it goes to X axis then to Y axis when selecting faces in other parts of the mesh." - according to docs, the tangent is based on the longest edge of the face. Think about it this way: what if the face was a perfect circle (which is impossible, but let's say it is) - then you wouldn't be able to determine in which direction to move the face, unless you want to favor some direction, e.g. horizontally. Maybe you want to detect the most horizontal edge and move along that edge. – Markus von Broady May 17 at 9:44
• Similarly blender.stackexchange.com/questions/207859/… blender.stackexchange.com/questions/118763/… blender.stackexchange.com/questions/118763/… all of which have issues if matched against the face normal axis displayed. (There is another that investigates the matrix used by the source code to display the axis, couldn't find) – batFINGER May 17 at 10:17
• @MarkusvonBroady Makes sense. I was actually avoiding the per face info and just use the normal information from a rayhit since the target objects are using modifiers. To use the face info I'd have to create an applied data linked to the scene to actually take the hit. I was looking around if a normal can somehow be converted to tangent but alas my math skills ain't up to the task. – Blenderguppy May 17 at 16:48
• @batFINGER I wonder if the mesh data can be locally transformed to match the orientation of the normal then just use that temporary switch to move the face to the x-y axis using local coordinates. After the operation, switch back to the old matrix. Bit hacky though. – Blenderguppy May 17 at 16:50
• @Blenderguppy take a look at the edit – Markus von Broady May 17 at 18:20