IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Delphi Discussion :

Detection point sur une ligne


Sujet :

Delphi

  1. #1
    Membre éclairé Avatar de PadawanDuDelphi
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2006
    Messages
    678
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : Bâtiment

    Informations forums :
    Inscription : Août 2006
    Messages : 678
    Points : 717
    Points
    717
    Par défaut Detection point sur une ligne
    Bonjour à tous,

    Mon problème est de detecter qu'un point "cliqué" appartient à une ligne tracée avec le pen. Au depart j'ai donc un tableau de TPoint, et je trace une ligne avec le pen entre ces TPoints...Au passage je crée également une région pour chaque segment de cette ligne.
    Puis j'utilise PtInRegion pour savoir si le point cliqué appartient à une région.
    Le problème c'est que les résultats sont très aléatoires, voir incohérents...
    Pièce jointe 5344
    La courbe en noir étant celle des régions, la bleue la courbe réellement tracée. lorsque je clic sur la courbe noire, pas de détection, mais lorsque je clic sur la bleue, parfois il y a détection (une fois sur deux environ).

    Pour aider à la compréhension, je joins également mon code pour tracer ma ligne et mes régions:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    procedure TLigne.TracerLigne(aPaint:TPaintBox);
    var seg:integer;
        points : array[0..3] of TPoint;
    begin
     
    setlength(Ri,length(lignes)-1);    //lignes est mon tableau de TPoints
     aPaint.Canvas.Pen.Width := 8;
     aPaint.Canvas.moveto(lignes[0].XPosition,lignes[0].YPosition);
    for seg:=0 to length(lignes)-2 do
    begin
      points[0] := point(lignes[seg].XPosition,lignes[seg].YPosition);
      points[1] := point(lignes[seg+1].XPosition,lignes[seg+1].YPosition);
      points[2] := point(lignes[seg+1].XPosition ,lignes[seg+1].YPosition +8);
      points[3] := point(lignes[seg].XPosition ,lignes[seg].YPosition + 8);
     
      Ri[seg] := CreatePolygonRgn(Points, 4, ALTERNATE);
      if (lignes[seg+1].TypeSection=0) then SetColor(clBlue)
      else SetColor(clRed);
       aPaint.Canvas.Brush.Color := aColor;
     
     aPaint.Canvas.Pen.Color:= aColor;
     aPaint.Canvas.lineto(points[1].X,points[1].Y);
      end;
    end;
    Quelqu'un arrive-til à savoir pourquoi mon raisonnement est mauvais et/ou connaiterais une meilleur façon de proceder?

    Merci beaucoup, par avance, de votre patience et de votre aide.

    @+.
    For crying out loud !

  2. #2
    Expert éminent Avatar de Graffito
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    5 993
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 993
    Points : 7 903
    Points
    7 903
    Par défaut
    Bonjour,

    Plutot que créer des régions, on pourrait faire un calcul de distance entre le point cliqué et les différents segments.
    " Le croquemitaine ! Aaaaaah ! Où ça ? " ©Homer Simpson

  3. #3
    Membre éclairé Avatar de PadawanDuDelphi
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2006
    Messages
    678
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : Bâtiment

    Informations forums :
    Inscription : Août 2006
    Messages : 678
    Points : 717
    Points
    717
    Par défaut
    J'y est penser un moment, mais je n'arrive pas à coder cette détection..
    For crying out loud !

  4. #4
    Expert éminent Avatar de Graffito
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    5 993
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 993
    Points : 7 903
    Points
    7 903
    Par défaut
    Bonjour,

    un petit bout de code que j'ai un peu simplifié mais pas testé (car le code original provenait d'un calcul sur sur une projection de carte).
    Il manque la distance point1 à point2 : D=sqrt(sqr(x1-x2)+sqr(x2-x1))
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    function DistPS(PC,PA,PB:point;var PP:point):single ;
    {
    distance from point C to segment AB 
     input   PC        <point>  coordinates of point C
             PA,PB     <point>  coordinates of segment extremities
             PP        <pointer> point on AB segment nearest of C
     result            <point>  distance 
    !}
     
    var
      XAC,XBC,XAB,XAC2,XAB2,XBC2,R,XBN : single ;
      N : GEO_llrec;
    begin
    try
    XAC:=DistPP(PC,PA) ; // GEO_DISTPP(PI,PJ)=Distance du point PI au point PJ  
    XBC:=DistPP(PC,PB) ;
    XAB:=DistPP(PA,PB) ;
    if XAB<0.01 then begin
       result:=XAC ;
       PP:=PA;
       exit ;
       end ;
    XAB2:=XAB*XAB ; XAC2:=XAC*XAC ; XBC2:=XBC*XBC ;
    if XBC2+XAB2<=XAC2 then begin
       result:=XBC ;
       PP=PB;
       exit ;
       end ;
    if XAC2+XAB2<=XBC2 then begin
       result:=XAC ;
       PP:=PA;
       exit ;
       end ;
    R:=2*XAB2*XBC2+2*XBC2*XAC2+2*XAC2*XAB2-XAB2*XAB2-XBC2*XBC2-XAC2*XAC2 ;
    if R>0.01
       then begin
            result:=SQRT(R) /(2*XAB);
               (* compute coordinate of nearest point *)
               try XBN:=sqrt(XBC2-(result*result))  except XBN:=0; end;
               PP.X:=PB.X+((XBN / XAB)*(PA.X-PB.X);
               PP.Y:=PB.Y+((XBN / XAB)*(PA.Y-PB.Y);
               end;
            end
       else begin
            (* C is on AB segment *)
            result:=0 ;
            PP:=PC;
            end;
    end ; (*DistPS*)
    " Le croquemitaine ! Aaaaaah ! Où ça ? " ©Homer Simpson

  5. #5
    Membre éprouvé

    Profil pro
    Inscrit en
    Mai 2003
    Messages
    582
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Mai 2003
    Messages : 582
    Points : 915
    Points
    915
    Par défaut
    Tu devrais peut-être regarder ce code...

    http://codecentral.borland.com/Item.aspx?id=18221

    en gros:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    //****************************************************************************//
    // Determines if a given point (xc,yc) is on a line.                          //
    // S*L = Distance of point from line.                                         //
    //****************************************************************************//
    function TForm1.IsPtOnLine(XA,YA,XB,YB,XC,YC, Tolerance: Double): Boolean;
    var
    L,R,S: Double;
    begin
      Result:=False;
      L:=SQRT(((XB-XA)*(XB-XA)+(YB-YA)*(YB-YA)));
      if l<>0 then
      begin
        R:= ((YA-YC)*(YA-YB)-(XA-XC)*(XB-XA))/(L*L);
        S:= ((YA-YC)*(XB-XA)-(XA-XC)*(YB-YA))/(L*L);
        if (r>0) and (r<1) then
            if Abs(S*L)<=Tolerance then Result:=True;  //s*l=distance
      end;
    end;
    Comment dupliquer un disque...ça vous intéresse?
    Tutoriel et code source delphi ici

  6. #6
    Membre éclairé Avatar de PadawanDuDelphi
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2006
    Messages
    678
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : Bâtiment

    Informations forums :
    Inscription : Août 2006
    Messages : 678
    Points : 717
    Points
    717
    Par défaut
    Merci beaucoup pour vos aides, grace à vous suis parvenu à réaliser quelque chose de sérieux, et surtout qui plait à mon patron.

    @+.
    For crying out loud !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Répartition de points sur une ligne
    Par travonz dans le forum Mathématiques
    Réponses: 3
    Dernier message: 29/01/2013, 23h09
  2. Detecter un changement sur une ligne dans une JTable
    Par RR instinct dans le forum Composants
    Réponses: 8
    Dernier message: 10/04/2008, 12h58
  3. nombres d'images sur une lign automatique
    Par AnKhCHFR dans le forum Balisage (X)HTML et validation W3C
    Réponses: 2
    Dernier message: 10/03/2005, 11h52
  4. Lien sur une ligne de tableau
    Par Oluha dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 09/02/2005, 11h36
  5. pointer sur une ligne d'un TStringGrid
    Par jeannot27 dans le forum C++Builder
    Réponses: 7
    Dernier message: 20/10/2004, 10h56

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo