Hi,
one of the part of a python script that I'm coding for Metashape creates an oriented quadrilateral shape (rotated and tilted) from the user input. When I check the dimension of the created shape using the "measure" option, the "Perimeter, 3D (m)" is not equal to the sum of the edges calculated from the shape coordinates that indeed correspond to the user input values. For example if the user input width: 5m and length: 5m the 3D perimeter from the measure option is 20.008 m, but if I get the shape coordinates and manually calculate the perimeter the result is 20.000 m.
I forgot to mention that all the math in the script are done using the coordinates in the ETRS89/UTM 31N reference system. I tried to run the same script but in a project that use the "Local coordinates" system and the "Perimeter, 3D (m)" is correct. It an issue related to the fact that I'm working with ETRS89/UTM 31N reference system? How the dimension in the "Measure shape" window are calculated? What I'm doing wrong?

To give you more context here is the part of the code that create the shape with some comment:
#np is numpy module
def Rx_zy (self, rad):
return np.array([[1, 0, 0], [0, np.cos(rad), np.sin(rad)], [0, -np.sin(rad), np.cos(rad)]]) #rotation around X clockwise
def Rz_yx(sel, rad):
return np.array([[np.cos(rad), np.sin(rad), 0], [-np.sin(rad), np.cos(rad), 0], [0, 0, 1]])#rotation around Z clockwise
def create_shape (self, azi, dip, shape_centroids): #azi= dip direction angle in degrees, dip= dip angle in degrees, shape_centroid = list of array that cointain a shape centroid for each selected shape and used as the centroid of the new created shape
all_created_shapes = []
w = self.float_spinboxes["Width"].value()#input width value in meters from a spinbox
l = self.float_spinboxes["Lenght"].value())#input lenght value in meters from a spinbox
R = np.matmul(self.Rz_yx(np.radians(azi)),self.Rx_zy(np.radians(dip)))#rotation matrix that combine a first rotation around X by dip value and a second one around Z by azi value
if self.planeline_cmb.currentText() == "Plane":#combobox text
geometry_type = Metashape.Geometry.Type.PolygonType
geometry = Metashape.Geometry.Polygon
V1 = np.array([-w/2, l/2, 0.0])
V2 = np.array([w/2, l/2, 0.0])
V3 = np.array([w/2, -l/2, 0.0])
V4 = np.array([-w/2, -l/2, 0.0])
shape_at_origin = np.array([V1,V2,V3,V4])#shape at origin (is this correct?) to be rotatated by azi and dip, and translated to the selected shape centroid.
else:
geometry_type = Metashape.Geometry.Type.LineStringType
geometry = Metashape.Geometry.LineString
V1 = np.array([0.0, l/2, 0.0])
V2 = np.array([0.0, -l/2, 0.0])
shape_at_origin = np.array([V1,V2])
for shape_centroid in shape_centroids:
rotated_shape = [np.matmul(R, vertex) for vertex in shape_at_origin]
translated_shape = [vertex + shape_centroid for vertex in rotated_shape]
translated_shape = np.array(translated_shape)
new_shape = chunk.shapes.addShape()
new_shape.geometry.type = geometry_type
new_shape.geometry = geometry ([Metashape.Vector(vertex) for vertex in translated_shape])
all_created_shapes.append(new_shape)
return all_created_shapes