Maths accuracy

I am writing a script which eventually will sweep a profile along a path (I know it can be done with curves but…). My first step is to check if the mesh is planar as this is required for the way I have thought of doing it. I have written the script quoted below which works fine for a mesh made flat along the axes but if you try rotating it it becomes non-planar with the figures equal to about 6 decimal places but then going of after that causing it to decide they are non planar. Is this just the accuaray that blender/python works to for its coordinates and has anyone a simple idea of how to get round it (something like rounding to 6 decimal places)?

Neil.


import Blender
from Blender import *
from Blender.Draw import *
from math import *

path=Object.GetSelected()[0]
print "Checking object "+path.name+"..."

mesh=NMesh.GetRawFromObject(path.name)

print "Calculating normal..."

x0,y0,z0=mesh.verts[0].co
x1,y1,z1=mesh.verts[1].co
x2,y2,z2=mesh.verts[2].co

xn=abs((y1-y0)*(z2-z0)-(z1-z0)*(y2-y0))
yn=abs((z1-z0)*(x2-x0)-(x1-x0)*(z2-z0))
zn=abs((x1-x0)*(y2-y0)-(y1-y0)*(x2-x0))

ln = sqrt(xn*xn+yn*yn+zn*zn)

xn /= ln
yn /= ln
zn /= ln

print "Normal: ("+str(xn)+","+str(yn)+","+str(zn)+")"
print "Checking vertices..."

planar=-1

for a in range(2,len(mesh.verts)):
	v=mesh.verts[a]
	xv,yv,zv=v.co

	xnv=abs((y1-y0)*(zv-z0)-(z1-z0)*(yv-y0))
	ynv=abs((z1-z0)*(xv-x0)-(x1-x0)*(zv-z0))
	znv=abs((x1-x0)*(yv-y0)-(y1-y0)*(xv-x0))

	lnv = sqrt(xnv*xnv+ynv*ynv+znv*znv)
	
	xnv /= lnv
	ynv /= lnv
	znv /= lnv

	if (xnv==xn)&(ynv==yn)&(znv==zn):
		print "Vertex "+str(v.index)+": OK"
	else:
		print "Vertex "+str(v.index)+": Non-planar!"
		print xv,yv,zv
		planar=0

if planar:
	print "Finished: mesh is planar!"
else:
	print "MESH NON-PLANAR!!!"

Ok,

you compute the norma takink the first three vertices and making a crossprod, right?

Then you compute a new normal taking as third vertex, sequentially, all other vertices of the mesh

THen you compute if the normals are the sam.

Instead than

if (xnv==xn)&(ynv==yn)&(znv==zn):

use

if (abs(xnv-xn)<epsilon)&
            (abs(ynv-yn)<epsilon)&
            (abs(znv-zn)<epsilon):

With (epsilon) a value you chose, say .0001

Stefano

Thanks.