Comparer coordonnées / TPoint

Résolu
Harvester_ Messages postés 36 Date d'inscription vendredi 31 décembre 2004 Statut Membre Dernière intervention 8 juillet 2007 - 8 août 2006 à 12:20
cs_Forman Messages postés 600 Date d'inscription samedi 8 juin 2002 Statut Membre Dernière intervention 6 avril 2010 - 8 août 2006 à 18:11
Je possède un quadrilatère ayant une forme ressemblant à celle d'un diamant ( -> "<>" ),
Je possède une coordonnée, et je souhaiterai savoir si cette coordonnée se situe dans ce quadrilatère ( je connais les coordonnées des 4 sommets ).

Je n'ai vu que des fonctions pour savoir si les points sont égaux, mais aucun pour comparer leur grandeur ( > & < ).

Merci bien.

10 réponses

DRJEROME Messages postés 436 Date d'inscription jeudi 9 janvier 2003 Statut Membre Dernière intervention 5 février 2015
8 août 2006 à 14:40
bonjour,

il faut utiliser les fonctions régions "CreatePolygonRgn" et "PtInRegion"

ça permet d'utiliser toutes les formes de figure que tu veux

Exemple concret pour voir si le point "Cible" est situé dans le "diamant" :


<hr />
var
diamant:array [1..4] of TPoint;
Cible:TPoint;
HR:HRGN;
begin
     diamant[1].x:= 10; diamant[1].y:=  0;
     diamant[2].x:= 20; diamant[2].y:= 10;
     diamant[3].x:= 10; diamant[3].y:= 20;
     diamant[4].x:=  0; diamant[4].y:= 10;

     Cible.x:=10; Cible.y:=10;



     HR:=CreatePolygonRgn(diamant,4,WINDING);
     if PtInRegion(HR,Cible.x,Cible.y) then  showmessage('dedans') else showmessage('dehors');
end;


<hr />

A+

DrJerome
3
Caribensila Messages postés 2527 Date d'inscription jeudi 15 janvier 2004 Statut Membre Dernière intervention 16 octobre 2019 18
8 août 2006 à 12:59
Salut,
C'est un problème de géométrie.
Tu calcules les équations des 4 droites.
Puis, pour être dans le quadrilatère, ton point doit à la fois être en dessous des 2 droites supérieures et au dessus des 2 droites inférieures.

Pour les formules:
http://perso.ensad.fr/ari/davidov/prog/encarts/droite.htm


 
0
jlen100 Messages postés 1606 Date d'inscription samedi 10 juillet 2004 Statut Membre Dernière intervention 25 juillet 2014 13
8 août 2006 à 14:17
salut,

j'ai fait quelques s rapprocahant dans le programme videosurveillance
dans l'unité choisevideo ou je teste la collision entre une caméra et
la poubelle (en fait l'angle supérieur  gauche de l'icone caméra
et le rectangle de l'image de la poubelle ça donnait ça:

Function TChoiceVideo.TestTrash(Sender: TObject; X, Y: Integer):boolean;
var H,B:Tpoint;
j:integer;
Hnt1:string;
flag:boolean;
// videoname:array[0..6] of string ;

begin
//**********on recupere la device
with sender as TControl do Hnt1:=Hint;
//*********on l'efface éventuellement de l'ecran
for j := 1 to 4 do
with Timage(findcomponent('IScreen'+inttostr(j))) do
begin
if Hint=Hnt1 then Hint:='';
end;
Result:=False;

/***** on récupère le coordonnées de la poubelle
with Trash do
begin
H.X:=Left;
H.Y:=Top;
B.X:=Left+Width;
B.Y:=Top+Height;
end;
with sender as TControl do
begin
Hnt1:=Hint;
visible:=true;

/*****le test est ICI
if (Top>H.Y)
and(left>H.X)
and(top-1 then begin flag:=true;end;
// end;
if flag then Shape1.Brush.Color:=clred else Shape1.Brush.Color:=clBtnFace;
visible:=flag;
// tag:=0;
result:=true;
end else Shape1.Brush.Color:=clBtnFace;
end;
end;


il y a beaucoup de chose ici qui ne te seront pas utiles car je pouvais déplacer plusieurs objet différents


@+

jlen
0
Harvester_ Messages postés 36 Date d'inscription vendredi 31 décembre 2004 Statut Membre Dernière intervention 8 juillet 2007
8 août 2006 à 14:27
Merci de vos réponses, j'avais déjà essayer ta technique jlen100 malhereusement trop imprécise pour les objets non rectangulaires/carré.

Je vais essayer de me pencher sur ta proposition Caribensila mais elle est bien compliquée !
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
jlen100 Messages postés 1606 Date d'inscription samedi 10 juillet 2004 Statut Membre Dernière intervention 25 juillet 2014 13
8 août 2006 à 14:41
il suffit de rajouter une condition au test pour savoir si le point est
à droite ou à gauche de la droite joignant le sommet opposés

@+

jlen
0
DRJEROME Messages postés 436 Date d'inscription jeudi 9 janvier 2003 Statut Membre Dernière intervention 5 février 2015
8 août 2006 à 14:44
regarde dans l'aide de l'api il y a d'autres fonctions rgn (régions) intéressantes (ellipses etc...)

DrJerome
0
Harvester_ Messages postés 36 Date d'inscription vendredi 31 décembre 2004 Statut Membre Dernière intervention 8 juillet 2007
8 août 2006 à 16:50
Merci à tous,
DRJEROME grand merci, les régions étaient pile poil ce qu'il fallait.

A la prochaine ;)
0
DRJEROME Messages postés 436 Date d'inscription jeudi 9 janvier 2003 Statut Membre Dernière intervention 5 février 2015
8 août 2006 à 17:08
Dernière précision ça ne prend en compte que ce qui est dans la forme (au sens strict)


càd que ce qui est pile-poil sur la ligne du pourtour de la forme n'est pas considéré "dedans" (ou alors il faut augmenter de 1 pixel le contour de la forme...)

DrJerome
0
cs_Forman Messages postés 600 Date d'inscription samedi 8 juin 2002 Statut Membre Dernière intervention 6 avril 2010 1
8 août 2006 à 17:53
Je rajoutterais au source de DRJEROME:

DeleteObject(HR)

à la fin (surtout si la fonction est susceptible d'être appelée beaucoup de fois). Ca sert à libérer la mémoire allouée par Windows.

Sinon, si le quadrilatère ABCD dans lequel tu veux tester la présence du point P est un parallélogramme (en particulier un losange) il y a une façon plus rapide (en connaissant les coordonnées des 3 points A,B et D):

function Test(P,A,B,D:TPoint):Boolean;
var
r,u,v:Integer;
begin
Result:=False;
r:=(D.X-A.X)*(B.Y-A.Y)-(B.X-A.X)*(D.Y-A.Y);
u:=(B.Y-A.Y)*(P.X-A.X)-(D.X-A.X)*(P.Y-A.Y);
v:=(D.Y-A.Y)*(P.X-A.X)-(B.X-A.X)*(P.Y-A.Y);
Result:=(u>=0) and (u<=r) and (v>=0) and (v<=r);
end;

Si je ne me suis pas trompé, cette fonction calcule les coordonnées du point P dans la base (A,AB,AD). Ces coordonnées sont stockées dans u et v, on vérifie qu'elles sont comprises entre 0 et 1, c'est à dire dans le parallélogramme (la fonction est un peu optimisée pour ne pas avoir à diviser par r).
0
cs_Forman Messages postés 600 Date d'inscription samedi 8 juin 2002 Statut Membre Dernière intervention 6 avril 2010 1
8 août 2006 à 18:11
Petite correction:

function Test(P,A,B,D:TPoint):Boolean;
var
r,u,v:Integer;
begin
r:=Abs((D.X-A.X)*(B.Y-A.Y)-(B.X-A.X)*(D.Y-A.Y));
u:=(B.Y-A.Y)*(P.X-A.X)-(D.X-A.X)*(P.Y-A.Y);
v:=(D.Y-A.Y)*(P.X-A.X)-(B.X-A.X)*(P.Y-A.Y);
Result:=(u>=0) and (u<=r) and (v>=0) and (v<=r);
end;
0
Rejoignez-nous