 |
 |
Developpement Empirium
|
 |
 |
 |
 |
|
 |
 |
 |
 |
 |
Leamas Mais faites le taire !!!
Inscrit le: 05 Jan 2010 Messages: 632
 |
Posté le: Sam 20 Avr 2013, 19:16 Sujet du message: @Max : Deplacement automatique - calculs de coordonnees |
 |
|
bonjour,
il parait que tu avais demandé une fonction capable de calculer un trajet optimal d'un point a un autre (sans prendre en compte les portails et vortex) quelque soit la vitesse (non nulle) de la flotte a déplacer et la distance a parcourir.
Une première mouture est disponible:
Code: | #include <stdio.h>
#include <stdlib.h>
#include <math.h>
int setsteps(int* stepx, int* stepy,int speed, int dx, int dy);
int settrajectories (int xd, int yd, int xa, int ya, int speed);
void giveresults(int abs[], int ord[] ,int size);
char checkresults(int abs[], int ord[], int size,int speed);
inline int c (float x)
{
return(x*x);
}
inline float min (float a, float b)
{
if (a<b)
{
return(a);
}
return(b);
}
int settrajectories (int xd, int yd, int xa, int ya, int speed)
{
if (speed<2)
{
printf("you are slower than a planet!!");
return (-1);
}
int dx=xa-xd, dy=ya-yd;
if ((dx==0)&(dy==0))
{
printf("don't move!");
}
float distance=sqrtf(dx*dx+dy*dy);//the ^ symbol is a binary operator!!!
int i=0;
int stepx=trunc(speed*dx/distance), stepy=trunc(speed*dy/distance), im=0;//im: is modified
im=setsteps(&stepx,&stepy, speed, dx, dy);
int nbstops=ceil((distance/(speed-1.5)));
//printf(" %d %f\n\n", nbstops, distance);
int stops_x[nbstops],stops_y[nbstops];//stops is not a struct because I am lasy today
setsteps(&stepx,&stepy, speed, dx, dy);
setsteps(&stepx,&stepy, speed, dx, dy);
setsteps(&stepx,&stepy, speed, dx, dy);
while(i<nbstops-1)
{
stops_x[i]=xd+stepx;
stops_y[i]=yd+stepy;
xd=stops_x[i];
yd=stops_y[i];
dx=xa-xd;
dy=ya-yd;
distance=sqrtf(dx*dx+dy*dy);
if(distance==0)
{
stepx=0;
stepy=0;
}
else
{
stepx=trunc(((speed*dx))/distance);
stepy=trunc(((speed*dy))/distance);
//printf("%d, %d", stepx, stepy);
im=setsteps(&stepx,&stepy, speed, dx, dy);
if(im)
{
setsteps(&stepx,&stepy, speed, dx, dy);
setsteps(&stepx,&stepy, speed, dx, dy);
setsteps(&stepx,&stepy, speed, dx, dy);
}
//printf(" %d, %d\n", stepx, stepy);
}
if(c(stepx)>c(dx))
{
stepx=dx;
}
if(c(stepy)>c(dy))
{
stepy=dy;
}
i++;
}
stops_x[i]=xa;
stops_y[i]=ya;
//giveresults(stops_x,stops_y, nbstops);
i=checkresults(stops_x,stops_y, nbstops, speed);
/*if (!i)
{
printf("an error occured");
}*/
return (i);
}
char checkresults(int abs[], int ord[], int size,int speed)
{
int i=1;
while (i<size)
{
if(c(abs[i]-abs[i-1])+c(ord[i]-ord[i-1])>c(speed+0.5))
{
return(0);
}
i++;
}
return(1);
}
void giveresults(int abs[], int ord[],int size)
{
int i=0;
while(i<size)
{
printf("%d|", abs[i]);
i++;
}
i=0;
printf("\n");
while(i<size)
{
printf("%d|", ord[i]);
i++;
}
}
int setsteps(int* stepx, int* stepy, int speed, int dx, int dy)
{
if (dx>0)
{
if(dy>0)
{
if(dx>dy)
{
if(c((*stepx)+1)+c((*stepy))<c(speed+0.5))
{
(*stepx)=(*stepx)+1;
return(1);
}
else if(c((*stepx))+c((*stepy)+1)<c(speed+0.5))
{
(*stepy)=(*stepy)+1;
return(1);
}
}
else
{
if(c((*stepy)+1)+c((*stepx))<c(speed+0.5))
{
(*stepy)=(*stepy)+1;
return(1);
}
else if(c((*stepy))+c((*stepx)+1)<c(speed+0.5))
{
(*stepx)=(*stepx)+1;
return(1);
}
}
}
else if (dy<0)
{
if((*stepx)>-(*stepy))
{
if(c((*stepx)+1)+c((*stepy))<c(speed+0.5))
{
(*stepx)=(*stepx)+1;
return(1);
}
else if(c((*stepx))+c((*stepy)-1)<c(speed+0.5))
{
(*stepy)=(*stepy)-1;
return(1);
}
}
else
{
if(c((*stepy)-1)+c((*stepx))<c(speed+0.5))
{
(*stepy)=(*stepy)-1;
return(1);
}
else if(c((*stepy))+c((*stepx)+1)<c(speed+0.5))
{
(*stepx)=(*stepx)+1;
return(1);
}
}
}
}
else if (dx<0)
{
if(dy>0)
{
if(-dx>dy)
{
if(c((*stepx)-1)+c((*stepy))<c(speed+0.5))
{
(*stepx)=(*stepx)-1;
return(1);
}
else if(c((*stepx))+c((*stepy)+1)<c(speed+0.5))
{
(*stepy)=(*stepy)+1;
return(1);
}
}
else
{
if(c((*stepy)+1)+c((*stepx))<c(speed+0.5))
{
(*stepy)=(*stepy)+1;
return(1);
}
else if(c((*stepy))+c((*stepx)-1)<c(speed+0.5))
{
(*stepx)=(*stepx)-1;
return(1);
}
}
}
else if (dy<0)
{
if(dx<dy)
{
if(c((*stepx)-1)+c((*stepy))<c(speed+0.5))
{
(*stepx)=(*stepx)-1;
return(1);
}
else if(c((*stepx))+c((*stepy)-1)<c(speed+0.5))
{
(*stepy)=(*stepy)-1;
return(1);
}
}
else
{
if(c((*stepy)-1)+c((*stepx))<c(speed+0.5))
{
(*stepy)=(*stepy)-1;
return(1);
}
else if(c((*stepy))+c((*stepx)-1)<c(speed+0.5))
{
(*stepx)=(*stepx)-1;
return(1);
}
}
}
}
return(0);
} |
Elle me semble fonctionelle... je n'aie eu aucune erreur sur:
Code: | #include <stdio.h>
#include <stdlib.h>
int setsteps(int* stepx, int* stepy,int speed,int,int);
int settrajectories (int xd, int yd, int xa, int ya, int speed);
int main()
{
srand(125);
scanf("echo\n");
int i,j,k,l,s,cpt=0,max=1000000;
while(cpt<max)
{
i=(rand()%2000)-1000;
j=(rand()%2000)-1000;
k=(rand()%2000)-1000;
l=(rand()%2000)-1000;
s=rand()%20+5;
if(!settrajectories(l,k,i,j,s))
{
printf("an error occured: %d %d %d",i,j,s);
cpt+=max;
}
cpt++;
}
i=-320;
j=-320;
s=2;
while(i<320)
{
j=-320;
while(j<320)
{
s=2;
while(s<20)
{
if(!settrajectories(0,0,i,j,s))
{
printf("an error occured: %d %d %d",i,j,s);
i+=1000;
j+=1000;
s+=1000;
}
s++;
}
j++;
}
printf("%d\n",i);
i++;
}
printf("nothing happened :-)");
return 0;
} |
Maintenant, j'imagine que tu ne souhaite pas l'avoir en C ni non plus devoir récupérer les points sur la sortie standard... Tu peut donc soit reprendre les idées (je suis dispo si un truc est pas clair) soit me faire recopier dans le bon langage et avec le bon prototype. Il faut remarquer que pour parer aux effets de louvoiement et de seuil notables a petite vitesse, un facteur correctif a été ajouté. Ce dernier implique souvent une longue suite de déplacements nuls une fois arrivé a destination.
Une version propre de ce code utiliserait donc des listes chainées et des structures. Ces concepts ne me sont pas étrangers.
Éventuellement, la convergence doit pouvoir être accélérée (d'un facteur 2, je dirais) en recodant sqrtf (<a href="forumv2.empirium.net/viewtopic.php?p=123900">cf ce fil</a>)
Bonne continuation
Leamas.
Ps: Lando doit 4 tonneaux de pisse de yack a TO, merci de t'assurer que le rédacteur ne les vide pas [/i] |
|
|
|
|
|
 |
 |
 |
 |
 |
Max Créateur du Jeu

Inscrit le: 23 Jan 2003 Messages: 8277
 |
Posté le: Dim 28 Avr 2013, 16:27 Sujet du message: |
 |
|
Merci pour ce travail.
Je vais préciser ma commande.
Je voudrais le code d'une fonction
function SeRapprocher( $XActuel, $YActuel, $XCible, $YCible, $Vitesse)
et qui renvoie un tableau
$Destination['X'] = coordonnée X du point permettant de se rapprocher de la cible
$Destination['Y'] = coordonnée Y du point permettant de se rapprocher de la cible
En gros, je ne veux pas savoir ce qu'il y a dans le code de la fonction, pourvu qu'elle prenne en entrées les variables citées et me renvoie un tableau de résultats comme indiqué.
Pour des soucis de maintenabilité, j'aimerais que le code soit en PHP, qu'il soit commenté, que les noms des variables soient en français, avec des noms explicites et longs, et avec une majuscule à chaque changement de mot ($VoiciUnExemple).
Ta fonction me semble extrêmement complexe par rapport à la commande. Mais c'est peut-être parce que tu as déterminé tout l'itinéraire.
Normalement, il s'agit de déterminer la ligne droite entre la position actuelle et la cible, et de trouver le point le plus éloigné qui se trouve sur cette droite, dans la limite de la vitesse du vaisseau. _________________ AUCUN HRP sur les forums RP merci
 |
|
|
|
|
|
 |
 |
 |
 |
 |
Leamas Mais faites le taire !!!
Inscrit le: 05 Jan 2010 Messages: 632
 |
Posté le: Dim 28 Avr 2013, 17:48 Sujet du message: |
 |
|
ok, je te fais sa...
En fait c'est mon premier jet qui faisait sa, dans le calcul d'un saut.
Mais cette solution n'est pas celle qui minimise (DistanceAvant-DistanceAprès): il reste parfois de quoi faire 1DU dans une direction, d'ou la complexité du code (mais en faisant speed+0,5 dans la determination de stepx initial, on devrait pouvoir éviter sa les 3/4 du temps). |
|
|
|
|
|
 |
 |
 |
 |
 |
Leamas Mais faites le taire !!!
Inscrit le: 05 Jan 2010 Messages: 632
 |
Posté le: Sam 04 Mai 2013, 14:37 Sujet du message: |
 |
|
voili voilou...
Je suis pas un pro du PHP, du coup j'ai pas fait de benchmark poussé (juste 4 tests), mais ceci devrais être opérationnel:
Code: |
function SeRapprocher( $XActuel, $YActuel, $XCible, $YCible, $Vitesse)//$Vitesse est dans N, ce qui n'est pas vérifié
{
$dx=$XCible-$XActuel; $dy=$YCible-$YActuel; $VraieVitesse=$Vitesse+0.5;
if(($dx*$dx+$dx*$dy)<$VraieVitesse*$VraieVitesse)
{
$destination['X']=$XCible;
$destination['Y']=$YCible;
Return($destination);
}
//nul besoin d'un else, car dans le premier cas, on est déja parti...
$distance=sqrt($dx*$dx+$dy*$dy);
$ax= ($dx>0)? floor($dx*($VraieVitesse)/$distance): ceil($dx*($VraieVitesse)/$distance);
$ay= ($dy>0)? floor($dy*($VraieVitesse)/$distance): ceil($dy*($VraieVitesse)/$distance);
$adx=abs($dx); $ady=abs($dy);//ceci permet d'économiser deux appels a abs en échange de 8 octets de mémoire, eux mêmes récupérés par l'allègement du code subséquent (si tu retire ce commentaire un poil trop long pour être utile sur un serveur)
$sdx=($dx>0)? 1:-1; $sdy=($dy>0)?1:-1;//ceci allège considérablement le code et permet donc d'économiser de la mémoire vive (dieu sait pourquoi le PHP n'est pas un langage compilé... serait-ce pour les injections SQL??????????????????????????)
if($dx*$dy!=0)
{
if($adx>$ady)
{
if ((($ax+$sdx)*($ax+$sdx)+($ay*$ay))<($VraieVitesse)*($VraieVitesse))
{
$ax=$ax+$sdx;
}
elseif ((($ay+$sdy)*($ay+$sdy)+($ax*$dx))<($VraieVitesse)*($VraieVitesse))
{
$ay=$ay+$sdy;
}
}
else
{
if ((($ay+$sdy)*($ay+$sdy)+($ax*$dx))<($VraieVitesse)*($VraieVitesse))
{
$ay=$ay+$sdy;
}
elseif ((($ax+$sdx)*($ax+$sdx)+($ay*$ay))<($VraieVitesse)*($VraieVitesse))
{
$ax=$ax+$sdx;
}
}
}
$destination=array(
'X'=>$XActuel+$ax,
'Y'=>$YActuel+$ay);
Return($destination);
} |
|
|
|
|
|
|
 |
 |
 |
 |
 |
Leamas Mais faites le taire !!!
Inscrit le: 05 Jan 2010 Messages: 632
 |
Posté le: Sam 04 Mai 2013, 14:43 Sujet du message: |
 |
|
désolé pour les noms peu clair, ceci est mieux:
Code: |
function SeRapprocher( $XActuel, $YActuel, $XCible, $YCible, $Vitesse)//$Vitesse est dans N, ce qui n'est pas vérifié
{
$DeplacementTotalEnX=$XCible-$XActuel; $DeplacementTotalEnY=$YCible-$YActuel; $VraieVitesse=$Vitesse+0.5;
if(($DeplacementTotalEnX*$DeplacementTotalEnX+$DeplacementTotalEnX*$DeplacementTotalEnY)<$VraieVitesse*$VraieVitesse)
{
$destination['X']=$XCible;
$destination['Y']=$YCible;
Return($destination);
}
//nul besoin d'un else, car dans le premier cas, on est déja parti...
$distance=sqrt($DeplacementTotalEnX*$DeplacementTotalEnX+$DeplacementTotalEnY*$DeplacementTotalEnY);
$AvenceeDansLaDirectionX= ($DeplacementTotalEnX>0)? floor($DeplacementTotalEnX*($VraieVitesse)/$distance): ceil($DeplacementTotalEnX*($VraieVitesse)/$distance);
$AvenceeDansLaDirectionY= ($DeplacementTotalEnY>0)? floor($DeplacementTotalEnY*($VraieVitesse)/$distance): ceil($DeplacementTotalEnY*($VraieVitesse)/$distance);
$ValeurAbsolueDuDeplacementEnX=abs($DeplacementTotalEnX); $ValeurAbsolueDuDeplacementEnY=abs($DeplacementTotalEnY);//ceci permet d'économiser deux appels a abs en échange de 8 octets de mémoire, eux mêmes récupérés par l'allègement du code subséquent (si tu retire ce commentaire un poil trop long pour être utile sur un serveur)
$DirectionEnX=($DeplacementTotalEnX>0)? 1:-1; $DirectionEnY=($DeplacementTotalEnY>0)?1:-1;//ceci allège considérablement le code et permet donc d'économiser de la mémoire vive (dieu sait pourquoi le PHP n'est pas un langage compilé... serait-ce pour les injections SQL??????????????????????????)
if($DeplacementTotalEnX*$DeplacementTotalEnY!=0)
{
if($ValeurAbsolueDuDeplacementEnX>$ValeurAbsolueDuDeplacementEnY)
{
if ((($AvenceeDansLaDirectionX+$DirectionEnX)*($AvenceeDansLaDirectionX+$DirectionEnX)+($AvenceeDansLaDirectionY*$AvenceeDansLaDirectionY))<($VraieVitesse)*($VraieVitesse))
{
$AvenceeDansLaDirectionX=$AvenceeDansLaDirectionX+$DirectionEnX;
}
elseif ((($AvenceeDansLaDirectionY+$DirectionEnY)*($AvenceeDansLaDirectionY+$DirectionEnY)+($AvenceeDansLaDirectionX*$DeplacementTotalEnX))<($VraieVitesse)*($VraieVitesse))
{
$AvenceeDansLaDirectionY=$AvenceeDansLaDirectionY+$DirectionEnY;
}
}
else
{
if ((($AvenceeDansLaDirectionY+$DirectionEnY)*($AvenceeDansLaDirectionY+$DirectionEnY)+($AvenceeDansLaDirectionX*$DeplacementTotalEnX))<($VraieVitesse)*($VraieVitesse))
{
$AvenceeDansLaDirectionY=$AvenceeDansLaDirectionY+$DirectionEnY;
}
elseif ((($AvenceeDansLaDirectionX+$DirectionEnX)*($AvenceeDansLaDirectionX+$DirectionEnX)+($AvenceeDansLaDirectionY*$AvenceeDansLaDirectionY))<($VraieVitesse)*($VraieVitesse))
{
$AvenceeDansLaDirectionX=$AvenceeDansLaDirectionX+$DirectionEnX;
}
}
}
$destination=array(
'X'=>$XActuel+$AvenceeDansLaDirectionX,
'Y'=>$YActuel+$AvenceeDansLaDirectionY);
Return($destination);
} |
|
|
|
|
|
|
 |
 |
 |
 |
 |
Landovan Mais faites le taire !!!

Inscrit le: 17 Sep 2009 Messages: 522 Localisation: Prima Ivee  |
Posté le: Sam 04 Mai 2013, 18:06 Sujet du message: |
 |
|
merci leamas pour tes efforts,
grace a toi , on va avoir les deplacements automatiques, ouuaaaaiss! |
|
|
|
|
|
 |
 |
 |
 |
 |
|
 |
 |
 |
 |
|
Vous ne pouvez pas poster de nouveaux sujets dans ce forum Vous ne pouvez pas répondre aux sujets dans ce forum Vous ne pouvez pas éditer vos messages dans ce forum Vous ne pouvez pas supprimer vos messages dans ce forum Vous ne pouvez pas voter dans les sondages de ce forum
|
|
|
 |