Getting Plane normal for distance_point_to_plane Function

Hello Guys,

i tryed to get the normal of a rotated plane but it won’t give me the right values…
I always get <Vector (0.0000, 0.0000, 1.0000)> which is the basic vector when creating a plane instead of the correct Vector <Vector (0.0000, 1.0000, 0.0000)>

it seems blender won’t update the normal after rotating

import mathutils
import bpy
from math import radians

bpy.ops.mesh.primitive_plane_add(enter_editmode=False, align=‘WORLD’, location=(0, 0, 0), scale=(1, 1, 1))

bpy.ops.transform.rotate(value=radians(90), orient_axis=‘X’)

obj = bpy.context.active_object

p = obj.data.polygons[0]

norm_vec = p.normal

def main():

Plane_point = mathutils.Vector((0.0, 0.0, 0.0))

point = mathutils.Vector((0.0, 0.0, 2.0))

distance = mathutils.geometry.distance_point_to_plane(point, Plane_point, norm_vec)

print(norm_vec)
return distance

if name == ‘main’:
print(main())

please help me, i need this value to calculate the shortest distance between a vertex and a plane. Do you also have any suggestions for that?

Thanks
StuEv

first- welcome to blenderartists.

second, use the code tags (three backticks: ```) when posting code- there’s some really weird formatting with your code that makes it hard to follow.

third: remember when working with vectors you need to keep in mind the orientation matrix of the object you’re working with. you rotated the object, not the face- so the normal is in local space. translating it into world space is just matrix math: world_normal = obj.matrix_world @ p.normal

Well using the world matrix works in many cases. But if you want to deal with all possible transformations you can do in blender, you need to do it this way:
world_normal = obj.matrix_world.inverted_safe().transposed().to_3x3() @ p.normal
There’s also a reduction of the matrix to 3x3 dimensions. Haven’t really checked what blender is doing when you @ multiply a 4x4 matrix with a 3 dimensional vector, but it could easily be, that they transform it as a point instead of a direction. By reducing it to 3x3 it ensures this.
The transpose of the inverse is important if you scale the object non-uniformly. You can read about it in more detail here:
https://www.scratchapixel.com/lessons/mathematics-physics-for-computer-graphics/geometry/transforming-normals

I’m looking at the specific example that was posted, which is a plane that was just created and rotated.

thanks a lot guys for the nice welcome, the code worked for me.

in the meantime i tried to flip the normal manually with euler rotation, but thats much easier.

Now i get good values when calculating the distance from a point to a plane but if i modify the location of the plane, i get the same values which is pretty odd:

import mathutils
import bpy
from math import radians


#add a plane with a given rotation
bpy.ops.mesh.primitive_plane_add(enter_editmode=False, align='WORLD', location=(0, 1, 0), rotation=(radians(90), 0, 0), scale=(1, 1, 1))

obj = bpy.context.active_object

p = obj.data.polygons[0]

norm_vec = obj.matrix_world.inverted_safe().transposed().to_3x3() @ p.normal


def main():
    
    
    # Vector on the Plane
    Plane_point = mathutils.Vector((0.0, 0.0, 0.0))


    # Vertex coordinates
    point = mathutils.Vector((0.0, 2.0, 0.0)) 


    # Compute distance between point and plane of camera
    distance = mathutils.geometry.distance_point_to_plane(point, Plane_point, norm_vec)
    
    distance_float = "{:.3f}".format(distance)
    
    #print(p.rotation)
    print(norm_vec)
    return distance_float


if __name__ == '__main__':
    print(main())

Output:

<Vector (0.0000, -1.0000, -0.0000)>
-2.000

normally i should get -1.000 for the calculated distance and there are also rounding errors, why I had to round the results in the output :/…

because that’s how the math works out, dunno how to explain it where it will make sense :slight_smile:

1 Like