Point dans cadre

Signaler
Messages postés
4
Date d'inscription
samedi 30 décembre 2006
Statut
Membre
Dernière intervention
25 juin 2007
-
Messages postés
4
Date d'inscription
samedi 30 décembre 2006
Statut
Membre
Dernière intervention
25 juin 2007
-
Bonjours à tous,

désoler de reformuler ma demande sur ce forum mais je m'etais trompé de forum ....alors pour ceux et celles qui l'auraient déjà lu dans le forum de maths n'en tenez pas compte...vous remerciant de votre compréhension.

je vais bref, je suis à la recherche d'un code en C qui pourrait me dire si un point en 3D est dans le cadre de n'importe quel polygone ou pas ?.....en résumer, je travail sur un code d'éclairement à l'intérieur d'un local et je dois faire des tests d'appartenance ou pas d'un point dans le cadre de vitrage. j'ai trouvé un petit code (sur le net) qui me dit ceci ( http://www.cours.polymtl.ca/inf6100/notes/chap7/chap7.html) :

Pour savoir si un point est à l'intérieur d'un polygone, la méthode la plus utilisée est de tracer une droite de ce point vers l'infini et de compter les intersections entre cette droite et les segments du polygone qui la croisent. Il faut bien sûr faire attention aux coins qui tombent juste sur la demi-droite.

* - : tracer une droite du point vers l'infini.

* - : calculer le nombre d'intersections entre cette droite et les segments formant le polygone.

* - : un nombre impair indique qu'on est à l'intérieur.

j'ai donc essayé d'écrire le code et de l'adapter à mes besoins mais voilà que je tombe sur un os. à chaque test le cpde me renvoi zero pour des raisons que j'ignore encore.Quelqu'un peu maider ???

merci d'avance.

le code est compilé sous DEVC++ et ressemble à cela :

/***************************************************************************
 *                                                                         *
 *   INPOLY.C                                                              *
 *                                                                         *
 *   Copyright (c) 1995-1996 Galacticomm, Inc.  Freeware source code.      *
 *                                                                         *
 *   Please feel free to use this source code for any purpose, commercial  *
 *   or otherwise, as long as you don't restrict anyone else's use of      *
 *   this source code.  Please give credit where credit is due.            *
 *                                                                         *
 *   Point-in-polygon algorithm, created especially for World-Wide Web     *
 *   servers to process image maps with mouse-clickable regions.           *
 *                                                                         *
 *   http://www.visibone.com/inpoly/inpoly.c                               *
 *                                                                         *
 *                                       6/19/95 - Bob Stein & Craig Yap   *
 *                                       stein@visibone.com                *
 *                                       craig@cse.fau.edu                 *
 *                                                                         *
 ***************************************************************************/
 
//appeler aussi algorithme de décompte de croisement
 
 #include <windows.h>
#include <stdio.h>
#include <math.h>
#define PI 3.1415927f
typedef struct
  {   float x;
   float y;
   float z;
  } T_Point3D;    
#define NB_MAX_SOMMETS 8
typedef struct
{
 T_Point3D LstPts[NB_MAX_SOMMETS]; // max octogone
 short   nSensDesc;
 short  nTypeSurf ;      // horizontale, verticale, inclinée, paroi, vitrage, GOE, PV, ?
 char szUnused[16] ; 
} T_Poly;
T_Poly PolyVit;
typedef struct
  {
  double X;    // dimension au sol de la zone selon X, i.e. dans l eplan du vitrage
  double Z;    // dimension au sol de la zone selon Z, i.e. dans le plan orthogonal au vitrage
  double Y; // pour pouvoir faire une zone sur le Mur et/ou le plafond
  //On ne prendra que les surfaces (càd 2 axes parmis les 3) pour définir les zones de calculs (la grille de calcul)
  } T_Zone;
 
typedef struct
  {   float X;    // dimenssion du block (face superieure) suivant l'axe x
   float Y;    // dimenssion du block (face supérieure) suivant l'axe y
  // float S;  // Surface du block (i.e X.Y)
         float Z; // dimenssion du block (face superieure) suivant l'axe z
  
  } T_Block;  
 
 
int                                /*   1=inside, 0=outside                */
inpoly(                            /* is target point inside a 2D polygon? */
T_Poly Vit,            /*   polygon points, [0]=x, [1]=y       */
int npoints,                       /*   number of points in polygon        */
 T_Point3D M)                  /*   x (horizontal) of target point   
                                       /*   y (vertical) of target point    */
{
     unsigned int xnew,ynew;
     unsigned int xold,yold,zold;
     unsigned int x1,y1;
     unsigned int x2,y2;
     int i;
     int inside=0;
     if (npoints < 3) {
          return(0);
     }
     xold=Vit.LstPts[npoints-1].x;
     yold=Vit.LstPts[npoints-1].y;
  
     for (i=0 ; i < npoints ; i++) {
          xnew=Vit.LstPts[i].x;
          ynew=Vit.LstPts[i].y;
         
          if (xnew > xold) {
               x1=xold;
               x2=xnew;
               y1=yold;
               y2=ynew;
          }
          else {
               x1=xnew;
               x2=xold;
               y1=ynew;
               y2=yold;
          }
          if (((xnew < M.x) == (M.x <= xold))         /* edge \"open\" at left end */
           && ((long)M.y-(long)y1)*(long)(x2-x1)
            < ((long)y2-(long)y1)*(long)(M.x-x1)) {
              // inside!=(inside);
               inside=inside+1;
          }
          xold=xnew;
          yold=ynew;
         // return (inside);
     }
    // printf(\"valeur donner dans la fonction principale 2 etape : %i\n\n\",inside);
   return(inside);
}
int main (void)
{
// int bTa;// CoordonneeXduBlock, CoordonneeYduBlock, CoorodonneZduBlock;
 
 //je declare mes deux variables
 
 T_Point3D point;
 T_Block Block; // ici je déclare et donc je reserve laplace
 T_Poly PolyVit;
 
 //je rempli mes structures. un exemple de point de coordonnées (4,3,2) et de dimenssion de block donnée (10,12,4).
 
 ///point.x=5;
 //point.y=3;
 //point.z=2;
 
 Block.X=4.0;
 Block.Y=4.0;
 Block.Z=4.0;
 
    PolyVit.LstPts[0].x = 0.0f;
    PolyVit.LstPts[0].y = 0.0f;
 PolyVit.LstPts[0].z = 0.0f;
    PolyVit.LstPts[1].x = 0.0f;
    PolyVit.LstPts[1].y = 0.0f;
 PolyVit.LstPts[1].z = 4.0f;
    PolyVit.LstPts[2].x = 4.0f;
    PolyVit.LstPts[2].y = 0.0f;
 PolyVit.LstPts[2].z = 4.0f;
    PolyVit.LstPts[3].x = 4.0f;
    PolyVit.LstPts[3].y = 0.0f;
 PolyVit.LstPts[3].z = 4.0f;
 PolyVit.nSensDesc =0;
 PolyVit.nTypeSurf =0;      // horizontale, verticale, inclinée, paroi, vitrage, GOE, PV, ?
 strcpy(PolyVit.szUnused,\"\");
// bTa = inside(point,PolyVit, int 4)
 //bTa = bIsTestPointDansCadre(point,&Block); // & est l'opérateur d'adressage
       // cad que &Block est l'adresse de Block et donc
                            // un pointeur sur Block
// printf(\"\nPoint 1 dans le plan ? : %d\n\", bTa);
 point.x=20.0;
 point.y=20.0;
 point.z=156.0;
 //bTa=inpoly(point,PolyVit, 4);
// if (bTa !=4)
// printf (\"le point est dedans\n\");
// else
// printf(\"le point est dehors\n\");
//inpoly(PolyVit,4, point);
 
printf(\" le test que j'ai fait me donne %u\n\",inpoly(PolyVit,4,point) );
 //bTa = bIsTestPointDansCadre(point,&Block);
 //printf(\"\nPoint 2 dans le plan ? : %d\n\", bIsTestPointDansCadre(point,&Block));
 
 system ("PAUSE");
 return 0;
   

    
}

4 réponses

Messages postés
966
Date d'inscription
samedi 3 avril 2004
Statut
Membre
Dernière intervention
4 mars 2010
4
J'ai testé : apparemment c'est ton vitrage qui est mal déclaré (faut faire gaffe à l'ordre des points)
Voici un test qui fonctionne (renvoie 1)

Block.X=4.0;
Block.Y=4.0;
Block.Z=4.0;

PolyVit.LstPts[0].x = 0.0f;
PolyVit.LstPts[0].y = 0.0f;
PolyVit.LstPts[0].z = 0.0f;
PolyVit.LstPts[1].x = 0.0f;
PolyVit.LstPts[1].y = 4.0f;
PolyVit.LstPts[1].z = 0.0f;
PolyVit.LstPts[2].x = 4.0f;
PolyVit.LstPts[2].y = 4.0f;
PolyVit.LstPts[2].z = 0.0f;
PolyVit.LstPts[3].x = 4.0f;
PolyVit.LstPts[3].y = 0.0f;
PolyVit.LstPts[3].z = 0.0f;
PolyVit.nSensDesc =0;
PolyVit.nTypeSurf =0;

// horizontale, verticale, inclinée, paroi, vitrage, GOE, PV, ?

point.x=2.0;
point.y=2.0;
point.z=156.0;

Au fait, quand on poste un code, c'est plus agréable de virer les instructions en commentaires...sinon c'est illisible.

Aussi dans ta fonction inpoly faut déclarer xold, xnew... en float puisqu'ils sont en float dans le type Poly.

Bonne prog.
Messages postés
4
Date d'inscription
samedi 30 décembre 2006
Statut
Membre
Dernière intervention
25 juin 2007

salut juju12,

merci pour ton aide précieux et tes conseils...c vraiment sympa de ta part. je vais revoir sa. entre temps j'ai mis en place aujourd'hui meme un autre code un peu similaire je pense mais qui est limiter à un polygone à quatres coté PoP1P2P3. sa ma donné des trucs interressants...regarde un coup en bas et dit moi ce que tu en pense (du moins si tu as du temps bien sur) ?..j'ai fait en sorte d'éviter les FALSE et TRUE du test en donnant des valeurs arbitraire moi meme au resultats obtenus afin de savoir si le point et ou n'est pas dans le cadre du polygone. Encore merci infiniment

#include <windows.h>
#include <stdio.h>
#include <math.h>
#define TRUE 1
#define FALSE 0


#define PI 3.1415927f


typedef struct
  {   float x;
   float y;
   float z;
  } T_Point3D;    


#define NB_MAX_SOMMETS 8


typedef struct
{
 T_Point3D LstPts[NB_MAX_SOMMETS]; // max octogone
 short   nSensDesc;
 short  nTypeSurf ;      // horizontale, verticale, inclinée, paroi, vitrage, GOE, PV, …
 char szUnused[16] ; 
} T_Poly;


T_Poly PolyVit;


char szBuffer[512]; // attn limitation taille ligne

int testeur2(T_Point3D t,T_Poly PolVit, int N)
{
  int c=0;  
    if (
         (
           (
              (
                 ( PolVit.LstPts[0].z <= t.z ) && (t.z < PolVit.LstPts[1].z )  //ici on test si les coordonnées du 
                                                                               
              )                                                                 
                ||                                                                           (                                                                                 ( PolVit.LstPts[1].z <= t.z ) && ( t.z < PolVit.LstPts[0].z ) //
                 
              )
       
                &&

                (
               
                    ( t.x <
                                         ( ( PolVit.LstPts[2].x - PolVit.LstPts[1].x ) * ( t.y - PolVit.LstPts[1].y ) / ( ( PolVit.LstPts[2].y - PolVit.LstPts[1].y ) + PolVit.LstPts[1].x ))
                    )
              ||
                    ( t.y <
                                         ( ( PolVit.LstPts[2].y - PolVit.LstPts[1].y ) * ( t.x - PolVit.LstPts[1].x ) / ( ( PolVit.LstPts[2].x - PolVit.LstPts[1].x ) + PolVit.LstPts[1].y ))
                    )
               )                                                  
            )
         )    
      ) 


      c=2;  //la valeur 2 indique que le point est dans le cadre  
                               
else c=5; //la valeur 5 indique que le point est en dehors du cadre
  return c;
}


 main()
{


 //je declare mes deux variables
 
 T_Point3D point;
 T_Poly PolyVit;
 
 //je rempli mes structures.
 
    PolyVit.LstPts[0].x = 0.0f;
    PolyVit.LstPts[0].y = 0.0f;
 PolyVit.LstPts[0].z = 0.0f;


    PolyVit.LstPts[1].x = 0.0f;
    PolyVit.LstPts[1].y = 0.0f;
 PolyVit.LstPts[1].z = 3.0f;


    PolyVit.LstPts[2].x = 4.0f;
    PolyVit.LstPts[2].y = 0.0f;
 PolyVit.LstPts[2].z = 3.0f;


    PolyVit.LstPts[3].x = 4.0f;
    PolyVit.LstPts[3].y = 0.0f;
 PolyVit.LstPts[3].z = 0.0f;
 PolyVit.nSensDesc =0;
 PolyVit.nTypeSurf =0;      // horizontale, verticale, inclinée, paroi, vitrage, GOE, PV, …
 strcpy(PolyVit.szUnused,"");
 
 point.x=3.0;
    point.y=34.0;
    point.z=1.0;


printf("le test que j'ai fait me donne soit 2 (le point est a l'interieur du cadre),\n\n soit 5 (le point est en dehors du cadre) : %d\n\n",testeur2(point,PolyVit, 4));


 system ("PAUSE");
 return 0;
   
 }
Messages postés
4
Date d'inscription
samedi 30 décembre 2006
Statut
Membre
Dernière intervention
25 juin 2007

j'ai fait les tests (sur le premier code que j'ai envoyé) et effectivement dans le cas que tu ma suggeré, c bon. mon souci c'est que le test devrait marcher quelque soit la position de la fenetre et ce n'est pas le cas. en effet, dans certaines situations le test ne me donne pas la vraie reponse (le point et ou n'est pas dans le cadre du polygone) . je pense que j'ai un souci de logique au niveau du test mais je ne vois pas encore lequel.......

en attendant je prefere me fier au deuxième code qu'au premier.

Bonne reception
Messages postés
4
Date d'inscription
samedi 30 décembre 2006
Statut
Membre
Dernière intervention
25 juin 2007

en faite je n"y comprend plus rien..meme mon deuxième programme me fait la meme betise....de l'aide s'il vous plait ....