et bien je dirais que les débuts sont encourageants
j'ai testé la fonction suivante :
MaLib.h
Code : Tout sélectionner
struct VECTOR
{
float x;
float y;
float z;
};
union floatlong
{
float f;
int l;
};
typedef struct VECTOR s_vecteur;
typedef union floatlong s_floatlong;
typedef unsigned int uint32;
#define PRODUIT_SCALAIRE(V1, V2) (V1.x * V2.x + V1.y * V2.y + V1.z * V2.z)
#define in(a)((uint32) a)
Test.c
Code : Tout sélectionner
int TestPointDansTriangle(s_vecteur *point, s_vecteur *pa, s_vecteur *pb, s_vecteur *pc){
float a, b, c, d, e;
s_vecteur e10, e20, vp;
s_floatlong x, y, z;
e10.x = pb->x - pa->x;
e10.y = pb->y - pa->y;
e10.z = pb->z - pa->z;
e20.x = pc->x - pa->x;
e20.y = pc->y - pa->y;
e20.z = pc->z - pa->z;
a = (e10.x * e10.x + e10.y * e10.y + e10.z * e10.z);
b = (e10.x * e20.x + e10.y * e20.y + e10.z * e20.z);
c = (e20.x * e20.x + e20.y * e20.y + e20.z * e20.z);
vp.x = point->x - pa->x;
vp.y = point->y - pa->y;
vp.z = point->z - pa->z;
d = (vp.x * e10.x + vp.y * e10.y + vp.z * e10.z);
e = (vp.x * e20.x + vp.y * e20.y + vp.z * e20.z);
x.f = (d * c) - (e * b);
y.f = (e * a) - (d * b);
z.f = x.f + y.f - (a * c) + (b * b);
return ((z.l & ~(x.l | y.l)) & 0x80000000);
// return ((in(z)& ~(in(x)|in(y))) & 0x80000000);
}
Elle est 50% plus rapide que ma fonction PureBasic, et apparemment plus précise, là je ne comprends pas pourquoi !
Pourquoi je dis plus précise ? j'ai fait un triangle sur le plan XY , et en mettant sa composante z à 0. autrement dit , dès qu'un point a une composante z différente de 0, il devrait se trouver en dehors du triangle, ben la fonction en C le détecte, et pas celle en PureBasic !
voila le code PB
Code : Tout sélectionner
Structure s_Vecteur
x.f
y.f
z.f
EndStructure
ImportC "StaticLibrary.lib"
TestPointDansTriangle.l(*point.s_Vecteur, *pa.s_Vecteur, *pb.s_Vecteur, *pc.s_Vecteur)
EndImport
#Epsilon=0.0001
Structure FloatLong
StructureUnion
f.f
l.l
EndStructureUnion
EndStructure
Macro SOUSTRACTION_VECTEUR(V, V1, V2)
V\x = V1\x - V2\x
V\y = V1\y - V2\y
V\z = V1\z - V2\z
EndMacro
Macro PRODUIT_SCALAIRE(V1, V2)
(V1\x * V2\x + V1\y * V2\y + V1\z * V2\z)
EndMacro
;La procédure d'erix14
Procedure TestPointDansTriangleErix14(*point.s_Vecteur, *pa.s_Vecteur, *pb.s_Vecteur, *pc.s_Vecteur)
Define.s_Vecteur e10, e20, vp
Define.f a, b, c, d, e
Define.FloatLong x, y, z
SOUSTRACTION_VECTEUR(e10, *pb, *pa)
SOUSTRACTION_VECTEUR(e20, *pc, *pa)
a = PRODUIT_SCALAIRE(e10, e10)
b = PRODUIT_SCALAIRE(e10, e20)
c = PRODUIT_SCALAIRE(e20, e20)
SOUSTRACTION_VECTEUR(vp, *point, *pa)
d = PRODUIT_SCALAIRE(vp, e10)
e = PRODUIT_SCALAIRE(vp, e20)
x\f = (d * c) - (e * b)
y\f = (e * a) - (d * b)
z\f = x\f + y\f - (a * c) + (b * b)
ProcedureReturn ((z\l & ~(x\l | y\l)) & $80000000)
EndProcedure
Define.s_Vecteur P, T1, T2, T3
;Le triangle
T1\x = 0.0
T1\y = 0.0
T1\z = 0.0
T2\x = 300.0
T2\y = 0.0
T2\z = 0.0
T3\x = 300.0
T3\y = 300.0
T3\z = 0.0
#Max = 100000
Dim Points.s_Vecteur(#Max)
For i = 1 To #Max
Points(i)\x = Random(600) - 300
Points(i)\y = Random(600) - 300
Points(i)\z = Random(600) - 300
Next i
For i = 1 To #Max
a = TestPointDansTriangleErix14(Points(i), @T1, @T2, @T3)
b = TestPointDansTriangle(Points(i), @T1, @T2, @T3)
If a <> b
Debug a
Debug b
Debug Points(i)\x
Debug Points(i)\y
Debug Points(i)\z
Debug "*********"
EndIf
Next i
Debug "fini"
End
Tps = ElapsedMilliseconds()
For j = 1 To 100
For i = 1 To #Max
TestPointDansTriangleErix14(Points(i), @T1, @T2, @T3)
Next i
Next j
Total1 = ElapsedMilliseconds()-Tps
Tps = ElapsedMilliseconds()
For j = 1 To 100
For i = 1 To #Max
TestPointDansTriangle(Points(i), @T1, @T2, @T3)
Next i
Next j
Total2 = ElapsedMilliseconds()-Tps
MessageRequester("test",Str(total1) + " / " + Str(Total2) ,0)