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

C Discussion :

Réordonner les sommets d'un polygon 3D en sens horaire (ou anti-horaire)


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Analyste d'exploitation
    Inscrit en
    Avril 2011
    Messages
    108
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Analyste d'exploitation
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2011
    Messages : 108
    Par défaut Réordonner les sommets d'un polygon 3D en sens horaire (ou anti-horaire)
    Je voudrais pouvoir réordonner les indices des sommets utilisés par un polygone 3D afin que ceux-ci respectent un ordre horaire
    (ou anti-horaire, pas bien important, le principal est que l'ordre de ces sommets soit correct afin de produire à coup sûr un polygon convexe)

    Aucun problème pour le faire en 2D, il suffit de calculer un segment de référence V1 entre le millieu et un des sommets, de lister les angles entre ce segment et l'ensemble des autres segments V2 allant du millieu du polygone vers chacun des sommets, de réordonner cette liste en ordre croissant des angles, puis enfin de réindexer en fonction les sommets utilisés par ce polygone

    Mais par contre, je ne retrouve aucune source C permettant de faire cela en 3D, bien que quasiment sûr que ça doive exister

    Ci-joint, le code que j'utilise pour réordonner correctement les sommets d'un polygone afin qu'ils soient listés dans le sens horaire mais ça ne semble marcher qu'avec des polygones inclus dans le plan XY, cf. en 2D et non pas en 3D ...

    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
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h> 
     
    #define MAX_GONE 	10
    #define MAX_POLYGONS 	100
     
    typedef struct _v3f
    {
    	float x, y, z;
    } v3f;
     
    typedef struct _polygon
    {
    	int poly;
     
    	int gone[MAX_GONE];
     
    } polygon;
     
    typedef struct _reindexed
    {
    	int v;
    	float angle;
    } indexed;
     
      v3f QuadVertices[4] = // quad with incorrect vertices ordering (non manifold)
    { 
    	{ -1.0f,  0.0f, 0.0f }, 
    	{  1.0f,  0.0f, 0.0f }, 
    	{  0.0f,  1.0f, 0.0f }, 
    	{  0.0f, -1.0f, 0.0f } 
    };
     
     
    v3f center;
    v3f v1;
    v3f v2;
     
    indexed Indexed[4];
     
    polygon Faces[MAX_POLYGONS];
     
    void MakeQuadConnectivity()
    {
    	Faces[0].poly = 4;
    	Faces[0].gone[0] = 0;
    	Faces[0].gone[1] = 1;
    	Faces[0].gone[2] = 2;
    	Faces[0].gone[3] = 3;
    }
     
     
    void PrintVertices( v3f *v, int num )
    {
    	int i;
     
    	for ( i = 0 ; i < num ; i++ )
    	{
    		printf("v[%d] = { %.0f , %.0f , %.0f } \n", 
    			i, 
    			v[i].x, 
    			v[i].y, 
    			v[i].z
    	 	); 
    	}
    }
     
     
    float Normalize( v3f *v )
    {
    	float dist1, dist2 = 0.0f;
     
    	dist2 += v->x * v->x;
    	dist2 += v->y * v->y;
    	dist2 += v->z * v->z;
     
    	dist1 = 1.0f / sqrt( dist2 );
     
    	v->x *= dist1;
    	v->y *= dist1;
    	v->z *= dist1;
    } 
     
     
    void ComputeAngles(v3f *v, int num, indexed *Idx)
    {
    	int i;
     
    	float cosinus, signe, angle;
     
     
    	for ( i = 0 ; i < num ; i++)
    	{
    		center.x += v[i].x;
    		center.y += v[i].y;
    		center.z += v[i].z;
    	}
     
    	center.x /= num;
    	center.y /= num;
    	center.z /= num;
     
    	v1.x = v[0].x - center.x;
    	v1.y = v[0].y - center.y;
    	v1.z = v[0].z - center.z; 
     
    	Normalize(&v1); 
    	// printf("v1 = {*%.0f, %.0f, %.0f } \n", v1.x, v1.y, v1.z); 
     
     
    	for ( i = 0; i < num ; i++)
    	{
    		v2.x = v[i].x - center.x;
    		v2.y = v[i].y - center.y;
    		v2.z = v[i].z - center.z;
    		Normalize(&v2); 
     
     
    		cosinus = v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
     
    		angle = acos(cosinus) * (180.0f / M_PI);
     
    		signe = v1.x * v2.y - v1.y * v2.x;
     
     
    		if ( signe < 0.0f )
    		{
    			angle += 180.0f;
    		}
     
     
    		Idx[i].v = i;
    		Idx[i].angle = angle;
     
    		// printf("Angle[%d] = %.0f \n", i, angle);
    	}  	
    }
     
    int Reindexation( const void *a, const void *b )
    {
    	indexed *pa, *pb;
     
    	pa = (indexed *) a;
    	pb = (indexed *) b;
     
    	return pa->angle - pb->angle;   
    }
     
     
    void PrintReindexed( v3f *v, int num, indexed *Idx, polygon *p )
    {
    	int i;
     
    	qsort( Idx, num, sizeof(indexed), Reindexation);
     
    	if ( p )  p->poly = num;
     
    	for ( i = 0 ; i < num ; i++ )
    	{
    		printf("v[%d -> %d] = {%.0f, %.0f, %.0f } [angle=%.0f] \n",
    			Idx[i].v, 
    			i,
    			v[ Idx[i].v ].x,
    			v[ Idx[i].v ].y,
    			v[ Idx[i].v ].z,
    			Idx[i].angle
    		);
     
    		if ( p ) p->gone[i] = Idx[i].v; 
    	}
    } 
     
    void PrintPolygon( polygon * p)
    {
    	int i;
     
    	printf("\nPolygon[%d] = [ ", p->poly);
     
    	for ( i = 0 ; i < p->poly ; i++ )
    	{
    		printf("%d ", p->gone[i] );
    	}
    	printf(" ] \n");
    }
     
     
     
     
     
    int main( int argc , char **argv )
    {
    	MakeQuadConnectivity();
     
    	printf("Avant reindexation \n");
    	PrintVertices(QuadVertices, 4);
     
    	printf("\nRéindexation ...\n\n");
    	ComputeAngles(QuadVertices, 4, Indexed);
     
    	PrintReindexed(QuadVertices, 4, Indexed, &Faces[0] );
     
    	PrintPolygon( &Faces[0] );
     
    	return 0;
    }
    Ce qui renvoie cela qui marche bien avec des polygones 2D mais ne fonctionne pas correctement avec des polygones 3D non inclus dans le plan XY

    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
     
    Avant reindexation 
    v[0] = {-1 , 0 , 0 } 
    v[1] = {1 , 0 , 0 } 
    v[2] = {0 , 1 , 0 } 
    v[3] = {0 , -1 , 0 } 
     
    Réindexation ...
     
    v[0 -> 0] = {-1, 0, 0 } [angle=0] 
    v[3 -> 1] = {0, -1, 0 } [angle=90] 
    v[1 -> 2] = {1, 0, 0 } [angle=180] 
    v[2 -> 3] = {0, 1, 0 } [angle=270] 
     
    Polygon[4] = [ 0 3 1 2  ]
    Je pense que tout le problème doit être dans cette partie qui ne semble fonctionner que dans le plan XY, du moins pour le calcul du signe ...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
                    cosinus = v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
     
    		angle = acos(cosinus) * (180.0f / M_PI);
     
    		signe = v1.x * v2.y - v1.y * v2.x;
     
     
    		if ( signe < 0.0f )
    		{
    			angle += 180.0f;
    		}

  2. #2
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    As-tu une définition mathématique de l'ordre total 3D que tu veux faire?
    Autrement-dit, en 3D, le sens horaire se fait par rapport à quelle direction et dans quel sens?

    Si ton polygone est plan, ca peut encore se faire par transformation de coordonnées: tu définis les axes x et y du plan du polygone, tu transpose ses sommets dans ces coordonnées, et tu appliques ton algo 2D.
    Mais si ton polygone n'est pas plat, ton ordre doit être plus général.

  3. #3
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 833
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 833
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par yannoo95170 Voir le message
    Ci-joint, le code que j'utilise pour réordonner correctement les sommets d'un polygone afin qu'ils soient listés dans le sens horaire mais ça ne semble marcher qu'avec des polygones inclus dans le plan XY, cf. en 2D et non pas en 3D ...
    Je n'arrive pas bien à visualiser ce que doit représenter un polygone 3D avec les sommets ordonnés dans un sens horaire. Le sens horaire s'applique à une forme 2D (typiquement un cadran de montre à aiguille). Mais en 3D ça donne quoi?
    Prenons pr exemple une pyramide égyptienne. Il y a donc un sommet en haut (A), puis les 3 sommets de la base (B, C et D). Ordonner ces quatre sommets dans le sens horaire ça donne quoi??? D'autant plus que j'ai présenté cette pyramide selon une orientation "arbitraire" (similaire à une vraie pyramide posée sur le sol) mais dans la réalité, elle peut-être orientée n'importe comment sans que cela ne change sa nature de pyramide...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  4. #4
    Membre confirmé
    Homme Profil pro
    Analyste d'exploitation
    Inscrit en
    Avril 2011
    Messages
    108
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Analyste d'exploitation
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2011
    Messages : 108
    Par défaut
    Tous les points du polygone sont bien sûr contenus sur le même plan, ce sont des polygones "plans", pas des pyramides

    Pour le sens, aucune importance que ce dans le sens horaire ou anti-horaire, le but est d'obtenir à coup sûr des polygones convexes, cf. surtout pas de polygones **NON** convexes
    (comme fait dans mon code en 2D via le "signe = v1.x * v2.y - v1.y * v2.x;" et le "if ( signe < 0.0f ){ angle += 180.0f; }" + le tri avec les angles classés dans l'ordre croissant ensuite, sauf que c'est sa version en 3D que je voudrais avoir, cf. calcul du signe en 3D plutôt qu'en 2D )

    A noter que le "signe = v1.x * v2.y - v1.y * v2.x;" est la composante Z du produit vectoriel entre V1 et V2
    => il me faudrait la même chose mais qui gère et assemble les composantes X, Y et Z "en même temps"

  5. #5
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 833
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 833
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par yannoo95170 Voir le message
    Tous les points du polygone sont bien sûr contenu sur un plan, ce sont des polygones "plans", pas des pyramides
    Dans ce cas, à quoi sert la 3° dimension ?

    Citation Envoyé par yannoo95170 Voir le message
    Pour le sens, aucune importance que ce dans le sens horaire ou anti-horaire, le but est d'obtenir à coup sûr des polygones convexes, cf. surtout pas de polygones **NON** convexes
    Rien ne garantit cela. Même un polygône avec tous ses sommets qui suivent dans l'ordre le cadran d'une montre peut parfaitement être "non" convexe...
    Nom : 440px-Simple_polygon.svg.png
Affichages : 162
Taille : 8,9 Ko
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  6. #6
    Membre confirmé
    Homme Profil pro
    Analyste d'exploitation
    Inscrit en
    Avril 2011
    Messages
    108
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Analyste d'exploitation
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2011
    Messages : 108
    Par défaut
    Ark, pas glop du tout ça

    A quoi sert la troisième dimension ?
    => bein pour pouvoir y gérer des polygones en 3D, pas seulement en 2D

    A noter que les polygones qui me seront donnés en entrée seront déjà convexes, c'est seulement le bon ordre des sommets qui n'est pas garanti et qu'il me faut réordonner

    En fait, ce seront des fans, cf. un contour dans un même plan dont il me faudra réordonner les sommets dans le bon ordre

    Dans cet exemple, l'ordre donné des sommets en entrée serait 0, 1,3,2,4,5,7,6 et il me faudrait les réordonner en sortie comme cette image en 0,1,2,3,4,5,6,7

    Nom : fans.jpeg
Affichages : 198
Taille : 6,7 Ko

    Mais je crois voir la "ruse"
    => il va me falloir pivoter/"faire tourner en 3D" chacun des polygones/fans sur le plan XY, cf. que leurs normales soient sur l'axe des Z, afin de pouvoir y extraire l'ordre correct ?

  7. #7
    Membre confirmé
    Homme Profil pro
    Analyste d'exploitation
    Inscrit en
    Avril 2011
    Messages
    108
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Analyste d'exploitation
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2011
    Messages : 108
    Par défaut
    Plus précisément, ce seront des pyramides telles que celle-ci, sauf que l'apex sera toujours au centre du "cercle", jamais au dessus ou en dessous
    => des pyramides plates = polygones plats convexes quoi
    (la base de Axis et Apex auront exactement les mêmes coordonnées, cf. celles du centre du "cercle" => la hauteur de la pyramide sera donc de 0 )

    Nom : ApexAxis.png
Affichages : 141
Taille : 4,9 Ko

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

Discussions similaires

  1. [Graphe] Obtenir la meilleur combinaison d'arrete afin de passer par tous les sommets
    Par Djobird dans le forum Algorithmes et structures de données
    Réponses: 4
    Dernier message: 15/04/2008, 21h56
  2. Réordonner les feuillets
    Par dessinateurttuyen dans le forum Visio
    Réponses: 0
    Dernier message: 04/02/2008, 10h06
  3. Réponses: 5
    Dernier message: 23/08/2007, 13h44
  4. [C#]Réordonner les élts d'un listView
    Par fafa139 dans le forum Windows Forms
    Réponses: 1
    Dernier message: 12/05/2006, 00h27
  5. [XSLT] Réordonner les éléments en sortie
    Par crossword dans le forum XSL/XSLT/XPATH
    Réponses: 1
    Dernier message: 05/12/2005, 09h37

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