http://jerome.le.chat.free.fr

Accueil > Blender > Scripts > Comparer des chiffres à virgule

Comparer des chiffres à virgule

les floats, c'est chiant à comparer. on observe par exemple dans la 3d view que 2 points sont au même endroit, mais la comparaison de vecteur renvoie parfois faux. de même après des calculs de vecteurs, des normalisations, des intersections etc, des coordonnées qui devraient être identiques n'ont plus le même nombre de décimales.sans oublier que :

print 3.0 - 2.1 == 0.9
> False

voila une fonction qui permet de comparer des 'floats' ou des coordonnées de diverses manières :

syntaxe :

cfloat(x,comp,y,floattest)

x et y sont deux floats ou deux listes de floats (par exemple des coordonnées de vertices) à comparer.

comp est l'opérateur :

'eq'   renvoie True si x et y sont égaux ou presque
'not'  renvoie True si x et y sont différents,
'in'   teste la présence d'un float/d'une liste de float x dans la liste/la liste de liste de float y. marche de la même manière qu'un if truc in liste, mais renvoie vrai si les décimales sont très proches.

floattest (défaut : 0.1). détermine la sensibilité du test

exemples d'utilisation :

je m'en sers beaucoup pour comparer les coordonnées au sein d'une mesh que je souhaite transformer ou analyser, ou pour d'autres fonctions type parallel(), aligned(), segmentIntersection() etc.

print cfloat(3.0 - 2.1,'eq',0.9)
>True

print cfloat(1,'eq',1.09)
>True

print cfloat(1,'eq',1.09,0.05)
>False

print cfloat(-123.8077,'eq',-123.8076,0.00011)
>True

print cfloat(-123.8077,'eq',-123.8076,0.0001)
>False


A=Vector([-123.807693481,-42.0447463989,10.568])
B=[-123.8077,-42.0447461234,10.569]
print cfloat(A,'eq',B)
>True

A=7.21
B=[5.15,12.35,7.20,4.5,78.9]
print cfloat(A,'in',B)
>True

A=[7.21,1.10,5.24]
B=[[5.15,7.21,5.24],[7.20,1.11,5.2325],[7.20,1.11,2.1]]
print cfloat(A,'in',B)
>True (A=B[1])

code :

def cfloat(x,comp,y,floattest=0.1) :
    try :t=y[0]
    except :
        x=[float(x)]
        y=[float(y)]
    if comp=="in" :
        for f in y :
            try :
                t=f[0]
                for v in y :
                    for ci,c in enumerate(x) :
                        if abs(c-v[ci]) > floattest : break
                    else : return True       
                return False
            except :
                if abs(x-f)) <= floattest : return True
        return False
    else :
        for i in range(len(x)) :
            if comp=="eq" and abs(x[i]-y[i]) > floattest : return False
            elif comp=="not" and abs(x[i]-y[i]) <= floattest : return False
        return True

 

Mise à jour le Mercredi, 05 Août 2009 12:10