| Bonjour, je n'avais pas alloué correctement la mémoire pour les structures que je définissais.
j'obtiens maintenant un résultat, par contre je ne suis pas sûre qu'il soit juste
ah oui, j'ai un warning que je n'arrive pas à regler : dans la fonction main , dans la fonction balayage 3eme parametre, pb de pointeur il n 'aime pas circuit(N, M)
que dois-je faire pour arranger ca?
merci beaucoup
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <math.h>
/* coef pour creer le circuit*/
#define N 2
#define M 2
#define NC ((N)*(COEF))
#define MC ((M)*(COEF))
#define COEF 4
/* constantes pour balayer */
#define PAS 90
#define DELTA_TETA (PI/PAS)
#define PI (4*atan(1.0))
/////////////////**************structures utilisées ******************//////////////////////////////////
struct s_point {int abscisse;int ordonnee;};
typedef struct s_point* points;
points creer_point ( int p_x, int p_y ){
points p = (points)malloc(sizeof(struct s_point));
p->abscisse = p_x; p->ordonnee = p_y;
return p;
}
struct s_direction { double s_teta; double s_dist_obst;};
typedef struct s_direction * p_direction;
p_direction creer_direction (double teta, double dist_obst) {
p_direction d = (p_direction)malloc(sizeof(struct s_direction));
d->s_teta = teta; d->s_dist_obst = dist_obst;
return d;
}
///////////////***********************CREATION DU CIRCUIT************//////////////////////////
/* fonction puissance */
int puiss (int x, int y) {
return (y > 0) ? (x*puiss(x, y-1)) : 1;
}
/* allocation de mémoire pour les tableaux à deux dimension */
int ** creer_mat ( int n, int m ) {
int ** mat = (int**) malloc (n* sizeof(int*));
int i,j;
for (i=0; i<n; i++) mat[i] = (int*) malloc (m* sizeof(int));
for (i=0; i<n; i++) {
for (j=0; j<m; j++) mat[i][j]=1;} /*initialisation des éléments de la mat à 1*/
return mat;
}
void affiche_circuit ( int ** circ, int n, int m) {
int l, k;
for (l=0; l<(n*COEF) ; l++) {
for (k=0; k<(m*COEF); k++) printf ("%d ", circ[l][k]);
printf ("\n");}
}
/* création de circuits */
int **circuit ( int n, int m ) {
int i,j; int k, l;
int n_fois_coef= n*COEF;
int m_fois_coef= m*COEF;
int **mat = creer_mat (n, m);
for (i=0; i<n; i++) {
printf ("entrer la ligne %d du circuit qui contient au plus %d 0 ou 1\n", i, m );
for (j=0; j<m; j++) scanf ( "%d", &mat[i][j]);}
int **circ= creer_mat ( n_fois_coef,m_fois_coef);
for (i=0; i<n; i++) {
for (j=0; j<m; j++) { /*on divise les cases pour avec un circuit de taille (n*COEF,m*COEF) */
for (l=(COEF*i); l<(COEF*(i+1)); l++) {
for (k=(COEF*j); k<(COEF*(j+1)); k++) circ[l][k]= mat[i][j];}
} /* obstacles : 0, libre : 1 */
}
for (j=0; j<(m_fois_coef); j++) {circ[0][j]=0; circ[n_fois_coef-1][j]=0;} /*bord du circuit cloturé */
for (i=0; i<m_fois_coef; i++) { circ[i][0]=0; circ[i][n_fois_coef-1]=0;}
affiche_circuit (circ, n, m);
return circ;
}
/***********************************fonctions secondaires pour la fonciton balayage *////////////
/* allocation de memoire pour tableau */
double * tab_radians ( int n) {
double * tab = (double*) malloc (n* sizeof(double ) );
int i;
for (i=0; i<n; i++) tab[i] = 0 ;
return tab;
}
/* recherche du maximum dans un tab de flottants*/
p_direction max_tab (double *tab,int taille, double cap){
int i;
p_direction d= creer_direction ( tab[0], cap -PI/2.);
double max_teta= d->s_teta;
for(i=1;i<taille;++i){
if (tab[i]> max_teta){ max_teta=tab[i]; d->s_dist_obst =(cap -PI/2. + i*DELTA_TETA);
}
}
return d;
}
/* calcul de la distance entre deux points du circuit */
/* ici je ne comprends pas pourquoi la fonction distance ne marche pas sous cette forme */
//double distance (points p1, points p2) {
// return sqrtf ( pow((((*p1).abscisse)-((*p2).abscisse)),2)+ pow(( ((*p1).ordonnee)- ((*p2).ordonnee)),2));
//}
double distance (int ax, int ay, int bx, int by) {
return sqrtf ( pow((ax-bx),2)+ pow((ay-by),2));
}
/*********************************LA FONCTION BALAYAGE *****************///////////////
p_direction balayage ( points position,double cap , int circ[NC][MC]) {
double teta ;int r=0; int k=1;
int a= ((*position).abscisse);
int b= ((*position).ordonnee);
points libre1= creer_point (a, b);
points libre2 = creer_point(a,b);
int i1= ((*libre1).abscisse);
int j1= ((*libre1).ordonnee);
int i2= ((*libre2).abscisse);
int j2= ((*libre2).ordonnee);
double * tab_teta = tab_radians (PAS);
for ( r=0; r<=PAS; r++) {
k=1;
teta = (cap- PI/2. + r*DELTA_TETA );
//printf ("r= %d, teta= %f \n", r, teta);
while (i2<(NC) && j2<(MC) && i2>=0 && j2>=0 && circ[i2][j2] !=0 ) { /* les 0 sont des obstacles*/
//printf ( "dans la boucle \n circ[i2][j2]= %d \n",circ[i2][j2]);
i1 =i2; j1=j2;
i2= (a + floor (k));
j2= (b+ floor (tanf (teta) *k));
//printf ("k= %d ", k);
//printf ( "i2= %d, j2= %d \n", i2, j2);
k++;
}
i2=a; j2=b;
// printf( "en sortie de boucle \n i2= %d, j2= %d \n", i2, j2);printf( "i1= %d, j1= %d \n", i1, j1);
// printf( "circ[i2][j2]= %d \n",circ[i2][j2] );
// printf( "circ[i1][j1]= %d \n",circ[i1][j1]);
//printf( " distance a l'obstacle= %lf \n",distance ( a, b, i1, j1));
tab_teta [r]= distance ( a, b, i1, j1);
}
//for ( r=0; r<=PAS; r++) printf ( " tab_teta (%d)= %f\n", r, tab_teta [r]);
return max_tab ( tab_teta, PAS, cap);
}
int main () {
points p1=creer_point (4,4);
//printf ("dist_obst= %lf\n", distance ( p1, p2));
p_direction d= balayage ( p1, PI/2.,circuit (N,M));
printf (" direction max =%lf\n", (d->s_teta)*180./PI ); /* indication en degré */
printf (" dist max =%lf\n", d->s_dist_obst);
return 0;
} Répondre à sonia393 | 11 loupius, le 4 mai 2009 à 23:19:52Eh oui c'est normal qu'il n'aime pas.
Pour simplifier le problème, déclare un tableau global 'int circ[NC][MC]'.
Une fois que le programme tournera comme tu le désireras, il sera alors temps d'essayer de le déclarer en dynamique.
Les deux lignes suivantes doivent aussi poser un problème à la compilation (avant c'étati mieux):
int a = ((*position).abscisse);
int b = ((*position).ordonnee);
Encore un petit effort ;-) Répondre à loupius | Boujour,
mon programme fonctionne, mais il y a certaines choses qui me laissent perplexe.
-dans le programme ci-dessous et plus précisément dans la fonction balayage, l'égalité de 2 structures n'a pas d'effet ( cf "position = libre1; )
-la fonction distance2 fonctionne correctement mais pas distance1 qui renvoie tjs 0
-la fonction max_tab ne fonctionne pas alors que max fonctionne
tous ces pbs me semblent venir d'une meme origine, à savoir un pb de définition de structure ou de leur utilisation, sinon d'un mauvais usage des pointeurs.
voici le programme qui marche :
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <math.h>
#define N 3
#define M 3
#define COEF 2 /* circuit de taille finale (MC, NC)*/
#define NC ((N)*(COEF))
#define MC ((M)*(COEF))
#define PAS 20 /*on choisit de regarder dans PAS directions*/
#define INC 0.001 /*on se balade sur la droite x=a+PAS*k avec a : abscisse de la position où l'on fait le balayage, k un compteur*/
#define DELTA_TETA (PI/(PAS))
#define PI (4*atan(1.0))
struct s_point {int abscisse;int ordonnee;};
typedef struct s_point* p_point;
p_point creer_point ( int p_x, int p_y ){
p_point p = (p_point)malloc(sizeof(struct s_point));
p->abscisse = p_x; p->ordonnee = p_y;
return p;
}
/* fonction puissance */
int puiss (int x, int y) {
return ((y > 0) ? (x*puiss(x, y-1)) : 1);
}
/* allocation de mémoire pour les tableaux à deux dimension */
int ** creer_mat ( int n, int m ) {
int ** mat = (int**) malloc (n* sizeof(int*));
int i,j;
for (i=0; i<n; i++) mat[i] = (int*) malloc (m* sizeof(int));
for (i=0; i<n; i++) {
for (j=0; j<m; j++) mat[i][j]=1;} /*initialisation des éléments de la mat à 1 (case libre)*/
return mat;
}
void affiche_circuit ( int ** circ, int n, int m) {
int l, k;
for (l=0; l<(n*COEF) ; l++) {
for (k=0; k<(m*COEF); k++) printf ("%d ", circ[l][k]);
printf ("\n");}
}
/* création de circuits */
int **circuit ( int n, int m ) {
int i,j; int k, l;
int n_fois_coef= n*COEF;
int m_fois_coef= m*COEF;
int **mat = creer_mat (n, m);
int **circ= creer_mat ( n_fois_coef,m_fois_coef);
for (i=0; i<n; i++) {
for (j=0; j<m; j++) { /*on divise les cases pour avec un circuit de taille (n*COEF,m*COEF) */
for (l=(COEF*i); l<(COEF*(i+1)); l++) {
for (k=(COEF*j); k<(COEF*(j+1)); k++) circ[l][k]= mat[i][j];}
} /* obstacles : 0, libre : 1 */
}
for (j=0; j<(m_fois_coef); j++) {circ[0][j]=0; circ[n_fois_coef-1][j]=0;} /*bord du circuit cloturé */
for (i=0; i<m_fois_coef; i++) { circ[i][0]=0; circ[i][n_fois_coef-1]=0;}
affiche_circuit (circ, n, m);
return circ;
}
/****************************************************************************/
/* allocation de memoire pour tableau */
double * tab_radians ( int n) {
double * tab = (double*) malloc (n* sizeof(double ) );
int i;
for (i=0; i<n; i++) tab[i] = 0 ;
return tab;
}
double mod_2pi (double f) {
while(f>2*PI) f-=2*PI;
while(f<0) f+=2*PI;
return f;
}
struct s_direction { double s_teta; double s_dist_obst;};
typedef struct s_direction* p_direction;
p_direction creer_direction (double teta, double dist_obst) {
p_direction d = (p_direction)malloc(sizeof(struct s_direction));
d->s_teta = teta; d->s_dist_obst = dist_obst;
return d;
}
/* recherche du maximum dans un tab de flottants*/
p_direction max_tab (double *tab,int taille, double cap){
int i;
p_direction d= creer_direction ( mod_2pi(cap-PI/2.), tab[0]);
double max_teta= (*d).s_dist_obst;
for(i=1;i<taille;++i){
if (tab[i]> max_teta){ max_teta = tab[i]; d->s_teta = mod_2pi(cap -PI/2.+i*DELTA_TETA);
}
}
return d;
}
/* calcul de la distance entre deux points du circuit */
double distance1 (p_point p1, p_point p2) {
double d= sqrtf (pow( p1->abscisse - p2->abscisse,2)+ pow(p1->ordonnee - p2->ordonnee,2));
return d;}
double distance2 (int ax, int ay, int bx, int by) {
return sqrtf ( pow((ax - bx),2) + pow((ay - by),2));
}
double max (double *tab, int taille ) {
int i; double max = tab[0];
for (i=1; i<taille; i++) {
if (max < tab[i]) max = tab[i];
}
return max;
}
#define SIGNE(teta) ((( teta < PI/2.) && (teta > -PI/2.)) ? 1 : (-1))
double balayage ( p_point position,double cap , int **circ) {
double teta ;int r=0; int k=1;
int a= (position->abscisse);
int b= (position->ordonnee);
p_point libre1= creer_point (a, b);
p_point libre2 = creer_point(a,b);
int i1= (libre1->abscisse);
int j1= (libre1->ordonnee);
int i2= (libre2->abscisse);
int j2= (libre2->ordonnee);
double * tab_teta = tab_radians (PAS);
for ( r=0; r<=PAS; r++) {
k=1;
teta = mod_2pi (cap- PI/2. + r*DELTA_TETA ); /* 2 cas : soit teta appartient à [-PI/2,PI/2] alors on ajoute à a (l'abscisse de la position) le calcul, sinon on le retranche */
while (i2<(NC) && j2<(MC) && i2>=0 && j2>=0 && circ[i2][j2] !=0 ) { /* les 0 sont des obstacles*/
i1 =i2; j1=j2;
i2= (a +SIGNE(teta)*floor (INC * k));
j2= (b + floor (tanf (teta) * INC * k));
k++;
}
i2=a; j2=b; /* ici aussi c est bizarre, si j'écris libre2 = position; ca n'a pas d'effet!! */
tab_teta [r]= distance2 (a, b, i1, j1); /* problème ici avec distance1*/
i1=a; j1=b;
}
for ( r=0; r<=PAS; r++) printf ( " tab_teta (%d)= %f\n", r, tab_teta [r]);
return max (tab_teta, PAS);
//return max_tab ( tab_teta, PAS, cap); /* et pour finir la fonction max fonctionne mais pas max_tab:!!!!!!*/
}
int main()
{
p_point p1=creer_point (1,1);
p_point p2=creer_point (1,2);
printf("Distance : %f\n", distance1(p1, p2));
int **circ = circuit (N,M);
double d= balayage ( p1, PI/2., circ);
return 0;
}
Répondre à godzilla393 | 13 loupius, le 8 mai 2009 à 15:04:19la fonction max_tab ne fonctionne pas alors que max fonctionne
Si elles doivent toutes les deux fonctionner. Seulement, dans la fonction 'double balayage...', 'return max...' retourne un double (correct) et 'return max_tab...' retourne une structure (le compilateur doit râler!).
D'autre part la fonction 'max_tab' est quasiment incompréhensible (avec max_teta qui représente une distance!); je propose la suivante qui est beaucoup plus rapide (1 seul appel à 'creer_direction): p_direction max_tab (double* tab, int taille, double cap)
{
int i, maxIndex = 0;
double maxTab = tab[0];
for (i=1; i<taille; i++)
if (tab[i]> maxTab)
maxTab = tab[maxIndex=i]; /* memorise la valeur max et l'angle */
return (creer_direction (mod_2pi(cap - PI/2.+ maxIndex*DELTA_TETA), maxTab));
}
l'égalité de 2 structures n'a pas d'effet
Si, il y a un effet mais pas celui escompté.
Dans le cas présent, 'libre1' et 'libres2' sont deux pointeurs sur des structures (qui ont été allouées et initialisées lors de leurs définitions).
En faisant libre1 = libre2, on dit que 'libre1' va pointer sur la structure pointée par 'libre2'. Donc ceci ne copie pas les valeurs de 'libre2' dans 'libre1', mais 'fusionne' les deux pointeurs. Première conséquence, l'ancienne structure 'libre2' est désormais pointée par deux pointeurs et toute modification faite via un des pointeurs se répercutera dans l'autre. Deuxième conséquence, l'adresse de la structure pointée précédemment par 'libre1' est perdue, elle ne pourra donc pas être libérée. Troisième conséquence, il ne faudra surtout pas libérer 'libre1' puis 'libre2' car ce serait libérer deux fois la même zone mémoire avec probablement un plantage à la clef.
NB: l'angle se note 'thêta' et non "teta' (cela aide à la lisibilité...). Répondre à loupius | Oui bien sur, j'avais changé la structure de la fonction comme ceci
p_direction balayage ( ....
.....
return max_tab ( tab_teta, PAS, cap);
}
int main () {
p_point p1=creer_point (1,1);
int **circ = circuit (N,M);
p_direction d= balayage ( p1, PI/2., circ);
printf (" direction max =%lf\n", (d->s_teta)*180/PI );
printf (" dist a l'obstacle max =%lf\n", (*d).s_dist_obst);
return 0;
}
renvoie
0 0 0 0 0 0
0 1 1 1 1 0
0 1 1 1 1 0
0 1 1 1 1 0
0 1 1 1 1 0
0 0 0 0 0 0
tab_teta (0)= 3.000000
tab_teta (1)= 3.000000
tab_teta (2)= 3.162278
tab_teta (3)= 3.605551
tab_teta (4)= 3.605551
tab_teta (5)= 4.242640
tab_teta (6)= 3.605551
tab_teta (7)= 3.605551
tab_teta (8)= 3.162278
tab_teta (9)= 3.000000
tab_teta (10)= 0.000000
tab_teta (11)= 0.000000
tab_teta (12)= 0.000000
tab_teta (13)= 0.000000
tab_teta (14)= 0.000000
tab_teta (15)= 0.000000
tab_teta (16)= 0.000000
tab_teta (17)= 0.000000
tab_teta (18)= 0.000000
tab_teta (19)= 0.000000
tab_teta (20)= 0.000000
direction max =45.000000
dist a l'obstacle max =3.000000 !!!!!! Répondre à godzilla393 | Merci pour ton explication sur libre1 = libre2;
c'est très claire
j'avais vu ca dans un livre mais ce n'etait pas des pointeurs.
que dois-je écrire si je veux égaliser le contenu des pointeurs? j'ai essayé *libre1 = *libre2;
mais ca ne marche pas. Pour moi cette affectation veut dire que le contenu de la structure vers laquelle pointe libre1 reçoit comme valeurs le contenu de la structure vers laquelle pointe libre2.
mais ca doit etre faux parce que ca ne marche pas.
peux tu m'éclairer davantage sur la question?
merci bcp Répondre à godzilla393 | 16 loupius, le 8 mai 2009 à 15:50:30C'est simple, il suffit d'écrire une fonction qui le réalise et là il n'y a pas de mystère, il faut égaler les différents paramètres, soit: void egale (p_point p1, p_point p2)
{
p1->abscisse = p2->abscisse;
p1->ordonnee = p2->ordonnee;
}
Bonne continuation. Répondre à loupius |
|
|
|
|
|
|