Area of the verts

I have list of verts that I know are in same plane (2D area).
Is there an easy way to get max area they form? The plane can have any orientation.
I just need to know the max size on area they form, like max square or rectangle they fit in.

I believe you can use the KDTree module for this operation:

https://docs.blender.org/api/current/mathutils.kdtree.html

How? I don’t get it

Did you take-a-look at / experiment with the code template example that have in the docs link?

import mathutils

# create a kd-tree from a mesh
from bpy import context
obj = context.object

mesh = obj.data
size = len(mesh.vertices)
kd = mathutils.kdtree.KDTree(size)

for i, v in enumerate(mesh.vertices):
    kd.insert(v.co, i)

kd.balance()


# Find the closest point to the center
co_find = (0.0, 0.0, 0.0)
co, index, dist = kd.find(co_find)
print("Close to center:", co, index, dist)

# 3d cursor relative to the object data
co_find = obj.matrix_world.inverted() @ context.scene.cursor.location

# Find the closest 10 points to the 3d cursor
print("Close 10 points")
for (co, index, dist) in kd.find_n(co_find, 10):
    print("    ", co, index, dist)


# Find points within a radius of the 3d cursor
print("Close points within 0.5 distance")
for (co, index, dist) in kd.find_range(co_find, 0.5):
    print("    ", co, index, dist)

i’m not really sure why kdtree was suggested for this, it’s a spatial search tree- it has no way of retrieving the bounds/area of a point cloud.

since you’re only interested in the area of a 2D polygon, I would recommend a shoelace area calculation algorithm, which can be easily implemented with numpy. it’s pretty straightforward, if you want to learn more about it there’s a good article with detailed explanations and examples here: https://www.geodose.com/2021/09/how-calculate-polygon-area-unordered-coordinates-points-python.html

One thing that is specific to your situation that the article will not cover: a rotated plane has 3 coordinates, and a shoelace algorithm requires two. Since your polygon is planar, only two of the coordinates are relevant- so you just need to get the local 2D positions relative to the plane’s normal and use those coordinates for the calculation. For example:

import bpy
 
obj = bpy.context.active_object
mesh = obj.data

normal = mesh.polygons[0].normal # replace this with whatever your plane normal is
plane_rot = normal.to_track_quat('Z').inverted()

verts = [(plane_rot @ v.co)[0:2] for v in mesh.vertices]
for v in mesh.vertices:
    v2d = (plane_rot @ v.co)[0:2] # since we tracked to Z we can throw out the Z coordinate, they will all be identical.
    print(f"{v2d}")