Page 2 sur 3

Publié : sam. 05/mars/2005 9:45
par Yves Rouquier
Merci pour vos reponces !

le plus dur maintenant vas etre de faire un code pas trop
"usine a gaz".

Publié : dim. 03/avr./2005 10:37
par Dr. Dri
Frenchy Pilou a écrit :Quand on trace les segments, on compare les X
On garde le plus petit, Xmini
On place le FillArea à Xmini-1, Y quelconque
Ce qui fait que la couleur du Fill sera à l'extérieur
On teste le X, Y courant :)
S'il a la couleur du Fill c'est qu'il est à l'extérieur itou :roll:
Sinon c'est qu'il est dedans :D
le problème c'est qu'avec des lignes aux coordonnées entières, ce n'est pas fiable...

L'algo des lignes je le connaissais (de "Philippe" du forum DB, y'a longtemps) et je pense que c'est le plus fiable...

Je connais les limites du fillarea parce que je me suis amusé à coder un petit "metal gear solid" en 2D avec justement les champs de vision et seul l'algo des droites fonctionnait à 100%!

Dri ;)

Publié : mar. 12/avr./2005 13:16
par Patrick88
tu peux aussi utiliser l'algorithme de cohen-sutherland

faire une recherche avec google...

patrick

Publié : lun. 06/juin/2005 9:55
par queskispace
Ou sinon t'utilise l'api windows qui a des fonctions qui font ce travail parfaitement :

Code : Tout sélectionner

HRGN CreatePolygonRgn(

    CONST POINT  *lppt,	// address of array of points 
    int  cPoints,	// number of points in array 
    int  fnPolyFillMode 	// polygon-filling mode 
   );
pour créer ta surface (une région dans le langage microsoft)

Et après :

Code : Tout sélectionner

BOOL PtInRegion(

    HRGN  hrgn,	// handle of region 
 
     int  X,	// x-coordinate of point  
    int  Y 	// y-coordinate of point  
   );	
Ou tu passe la valeur que tu viens de recupérer en premier paramètre.
C'est super simple et c'est super optimisé.
Par conter pour le mode t'a deux possibilité : ALTERNATE ou WINDING et je sais pas lequel conviens, le meilleur moyen c'est d'essayer !!!

Publié : mer. 08/juin/2005 9:35
par Yves Rouquier
Bonjour !

Cette fonction de l'api est exactement ce que je recherche .

Mais j'aimerais trouver la source de cette fonction même en C C++
pour créer ma propre procedure sous purebasic.

l'algo cohen-sutherland est utiliser surtout pour faire du "clipping"
c'est a dire decouper un vecteur dans une fenetre othogonale ,
c'est plutot simple !

Savoir si un point est dans un polygone est une autre histoire !
formuler l'algo en language "humain" est une chose le transposer
en est une autre !

j'avoue avoir des difficultés et aussi un peu la fléme sur ce coup là.

Publié : sam. 03/sept./2005 12:45
par Dr. Dri
j'ai essayé l'api ptinregion... ca fonctionne nickel chez moi... ma region (hRgn) par contre, je la libère comment ? DeleteObject_() ??

Dri

Publié : sam. 03/sept./2005 17:57
par Dr. Dri
Autre problème, j'ai testé avec XP et ca ne fonctionne pas :(
y'a une différence d'utilisatoin entre XP et 9x ?

Dri

Publié : sam. 03/sept./2005 20:11
par Dr. Dri
My program, working perfectly in Win98 seemed to go awry in WinXP. I tracked that the problem was that CreatePolygonRgn() failed. CreateRectRgn() works, but CreatePolygonRgn() fails. Are there any known issues?
http://www.codeguru.com/forum/archive/i ... 27124.html

Je suis donc pas le seul... je continue de chercher des pistes mais si quelqu'un peut maider je dis pas nan :mad:

Dri :(

Publié : sam. 03/sept./2005 22:57
par Dr. Dri
probleme réglé, la constante #winding peut etre remplacée par un 0 sur 98 mais pas XP...

je manque encore de rigueur lol

Dri

Publié : dim. 04/sept./2005 12:57
par Flype
Dr. Dri a écrit :j'ai essayé l'api ptinregion... ca fonctionne nickel chez moi... ma region (hRgn) par contre, je la libère comment ? DeleteObject_() ??

Dri
oui dr dri, cf doc ms :
The DeleteObject function deletes a logical pen, brush, font, bitmap, region, or palette, freeing all system resources associated with the object. After the object is deleted, the specified handle is no longer valid.

Publié : dim. 04/sept./2005 13:56
par Dr. Dri
Merci ^^
Tout fonctionne nickel sur tous les windows désormais :D

Dri

Publié : dim. 25/sept./2005 22:35
par Backup
je fais remonter ce post car je crois qu'il existe une methode toute simple

qui consiste a tracer un segment de droite a partir du point que l'on observe !

si ce segment coupe 2 lignes (verifier le chemin pendant le tracage avec point() ) cela veut dire que l'on est en dehors du polygone

si aucune ligne n'est coupé cela signifie que l'on est toujours en dehors
du polygone !!

par contre si l'on coupe une seul ligne , cela signifie forcement que l'on se trouve dans le polygone ! :D

Publié : lun. 26/sept./2005 12:23
par Dr. Dri
ce n'est pas deux ou une ligne mais bel et bien un nombre pair ou impair -> l'algo des lignes dont on parle plus haut

Dri ;)

Publié : mar. 27/sept./2005 19:10
par Yves Rouquier
Bonsoir ,

Voici la definition de l'algo en" français ":

Soit (X,Y) un point et { (X1,Y1) , (X2,Y2) , … , (Xn,Yn) } un polygone connexe à n sommets (chacun des sommets est bien entendu distinct d'un autre).
Nous commençons par vérifier si (X,Y) appartient à l'un des segments (Xi,Yi), (Xi+1,Yi+1) auquel cas nous avons terminé.

Si ce n'est pas le cas, nous calculons et plaçons dans une liste les n-1 pentes des segments de droite (Xi,Yi), (Xi+1,Yi+1).
Nous calculons et ajoutons à la liste les n pentes des droites (X,Y) (Xi,Yi).

La liste que nous venons de constituer est triée par ordre croissant (ou décroissant), et nous définissons la pente p comme la moyenne arithmétique des deux premières pentes distinctes de la liste triée.

Le segment de droite S de pente p issu du point (X,Y) et dont l'autre extrémité a pour abscisse le nombre max{X1, X2, .., Xn} vérifie les conditions requises pour appliquer la règle mise en évidence.

A l'aide d'une itération, nous vérifions si le segment de droite S entre en intersection avec chacun des segments qui constituent le polygone, et incrémentons un compteur (initialement nul) dans ce cas.


Le test de parité de la valeur finale du compteur permet de conclure.


le lien vers la page de Christophe Faivre
http://www.iag.asso.fr/articles/intersection.htm



J'ais depuis eu la chance d'utiliser des logiciels tel que mapinfo et arcmap
qui sont spetialisés dans ce type d'operations.

Mais je cherche toujours à faire ma propre fonction utilisable avec des float !

A bientot

Publié : mar. 27/sept./2005 23:08
par Backup
ben tu pourra toujours utiliser la fonction polygone ci-dessous pour tes tests ! :D

addapter d'un code anglais !

Code : Tout sélectionner

#dobro=1
#Police=1
#Sprite=1
#PI=3.1415926
Declare polygone(x.l,y.l,taille.l,angle.l,rotation.f,color.l,t)
; ***********************************
Resultat = InitSprite()
FontID = LoadFont(#Police, "arial", 18, #PB_Font_Bold )
EcranX = GetSystemMetrics_(#SM_CXSCREEN):;=largeur de l'ecran
EcranY = GetSystemMetrics_(#SM_CYSCREEN):;=hauteur de l'ecran
  WindowID = OpenWindow(1, 0, 0, EcranX, EcranY,  #PB_Window_SystemMenu|#PB_Window_BorderLess |#PB_Window_ScreenCentered , "hello")
  
  WindowID = WindowID(1)
  Result = OpenWindowedScreen(WindowID,0,0,800, 600, 1, 0,0)
  
  
  
  Resultat = InitMouse() 
  Repeat
    ExamineMouse()
    Event=WindowEvent() 
    If MouseButton(2)
      End
    EndIf
    
    
    
    ;Star(x.l,y.l,intrad.l,n.l,phase.f,color.l)
    
    x.l=400 ;location x
    y.l=300 ; location y
    taille.l=100
    angle.l=4 ; pour un triangle  4 pour un carre , 8 pour un octogone ect ...
    rotation.f=180
    
    color.l=RGB($FF,$FF,$80)
    For t=0 To 360
    ; Delay (200)
    rotation.f=t 
      polygone(x.l,y.l,taille.l,angle.l,rotation.f,color.l,t)
     FlipBuffers():; affiche l'ecran
      ClearScreen(0,0,0) 
      ExamineMouse()
      Event=WindowEvent() 
      If MouseButton(2)
        End
      EndIf
    Next t
    

    
    
  Until Event=#PB_Event_CloseWindow
  
  
  
  
  Procedure  polygone(x.l,y.l,taille.l,angle.l,rotation.f,color.l,t)
    If angle.l=4 

    Else
    
    EndIf
     rotation.f= rotation.f*0.01745329
    StartDrawing(ScreenOutput() )
    DrawText(StrF( t))
    alpha.f=2*(#PI/angle)
    For t.l=1 To angle
      d1.f=(t-1)*alpha+rotation.f
      d3.f=t*alpha+rotation.f
      LineXY(x+taille*Sin(d1),y+taille*Cos(d1),x+taille*Sin(d3),y+taille*Cos(d3),color)
    Next
    StopDrawing()
  EndProcedure