Algo

Programmation d'applications complexes
Yves Rouquier
Messages : 40
Inscription : mar. 23/mars/2004 10:23

Message par Yves Rouquier »

Merci pour vos reponces !

le plus dur maintenant vas etre de faire un code pas trop
"usine a gaz".
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

Message 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 ;)
Patrick88
Messages : 1564
Inscription : mer. 21/janv./2004 18:24

Message par Patrick88 »

tu peux aussi utiliser l'algorithme de cohen-sutherland

faire une recherche avec google...

patrick
queskispace
Messages : 3
Inscription : ven. 12/nov./2004 2:47

Message 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 !!!
Yves Rouquier
Messages : 40
Inscription : mar. 23/mars/2004 10:23

Message 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à.
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

Message 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
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

Message 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
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

Message 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 :(
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

Message 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
Avatar de l’utilisateur
Flype
Messages : 2431
Inscription : jeu. 29/janv./2004 0:26
Localisation : Nantes

Message 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.
Image
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

Message par Dr. Dri »

Merci ^^
Tout fonctionne nickel sur tous les windows désormais :D

Dri
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message 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
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

Message 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 ;)
Yves Rouquier
Messages : 40
Inscription : mar. 23/mars/2004 10:23

Message 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
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message 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 


Répondre