1

Salut à tous!

Je code depuis quelques temps une classe C++ permettant de gérer des coordonnées spatiales.
La classe en est arrivée à un point où toutes les fonctions primordiales sont faites et où il est temps de passer au debuggage grandeur nature.
Le projet ce trouve sur http://code.google.com/p/clocate/ ; merci à tous de me dire ce qu'il faudrai revoir.

En gros la classe permet de gérer des coordonnées de type XYZ et GPS. Parmi les coordonnées GPS il est possible d'utiliser les degrés décimales -Dd- (4.4242°), degrés,minutes décimales -DMd- (34°45.6452'), degrés,minutes,secondes décimales -DMSd- (12°55'3.23425") et les degrés,minutes,secondes -DMS- (7°43'9")

La classe :
-gère un certain nombre d'ellipsoïdes (ne pas hésiter à me le dire pour en ajouter)
-peut convertir : Dd<=>DMd<=>DMSd<=>DMS (attention : convertir de DMSd vers DMS enlève de la précision)
-peut convertir : XYZ<=>GPS (attention : cela enlève de la précision aussi) - ceci grâce aux ellipsoïdes justement
-calculer des distances entre deux points
-exporter les coordonnées sous forme binaire, chaine de caractères, XML ou dans des variables (selon le prototype).
-permet les opérations = (copie d'un objet) et == (comparaison de deux objets ; != est aussi disponible)

Exemple :
CLocate monPoint;
monPoint.setDataFromValue( (long double)1532,(long double)65,(long double)9432 ); //Point de type XYZ
monPoint.setEllipsoid( CLocate::ELLIPSOID_wgs84);
monPoint.setCoordinateType( CLocate::COORD_DMSd); //Converti de XYZ vers degrés,minutes,secondes décimales
std::cout << monPoint.getDataAsXML() << std::endl; //affichage des coordonnées au format XML
if (monPoint != unAutrePoint ) std::cout << monPoint.getDistance( unAutrePoint ) << std::endl; //Calcul la distance avec un autre point s'ils sont différents l'un de l'autre

2

return (long long double)sqrt( pow((s.x - d.x),2) + pow((s.y - d.y),2) + pow((s.z - d.z),2) );

	distance = (long long double)((EARTH_R) * (PI/2 - asin( sin(DEGtoRAD(d_lat.d)) * sin(DEGtoRAD(s_lat.d)) + cos(DEGtoRAD(d_long.d) - DEGtoRAD(s_long.d)) * cos(DEGtoRAD(d_lat.d)) * cos(DEGtoRAD(s_lat.d)))));
	if ( s_alt != d_alt )
		distance = (long long double)sqrt( pow(distance,2) + pow((s_alt - d_alt),2) );

... #treeek#

(bon ok les perfs sont probablement pas importantes, mais... eek... O_O (enfin sinon, ca a l'air chouette... ^^))
avatar
HURRRR !

3

Faut dire, déjà le pow(distance, 2) fait peur.

4

long long double??? Alors, long double j'ai déjà vu (ça existe en C99 au moins), mais long long double?!
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

5

je comprendrais jamais les gens qui utilisent des this->myparam dans des methodes de classe.

6

KK> jamais vu non plus grin ptetre des flottants 128 ou 160 bits.. triouitritop
avatar
HURRRR !

7

nEUrOO (./5) :
je comprendrais jamais les gens qui utilisent des this->myparam dans des methodes de classe.

C'est généralement pour lever les ambiguitée, surtout si la définition de la class n'est pas sous les yeux, pour de tres grosses classes c'est quand meme plus lisible, au moins on est sur que c'est un attribut de la classe et pas une variable locale.
avatar
Proud to be CAKE©®™


GCC4TI importe qui a problème en Autriche, pour l'UE plus et une encore de correspours nucléaire, ce n'est pas ytre d'instérier. L'état très même contraire, toujours reconstruire un pouvoir une choyer d'aucrée de compris le plus mite de genre, ce n'est pas moins)
Stalin est l'élection de la langie.

8

(il suffit d'avoir une convention de nommage suffisamment propre pour les variables membres et / ou les locales, et t'as pas besoin de faire ca hein...)
avatar
HURRRR !

9

Il y a un contexte où this est obligatoire:
class myclass {
  private:
    int foo;
  public:
    myclass(int foo) {
      this->foo = foo;
    }
};
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

10

(il suffit d'avoir une convention de nommage suffisamment propre pour les variables membres et / ou les locales, et t'as pas besoin de faire ca hein...)

trioui
avatar
HURRRR !

11

Et puis je vois pas en quoi ça gene, le code généré est le meme, est c'est tjrs plus lisible quoi qu'il en soit..
avatar
Proud to be CAKE©®™


GCC4TI importe qui a problème en Autriche, pour l'UE plus et une encore de correspours nucléaire, ce n'est pas ytre d'instérier. L'état très même contraire, toujours reconstruire un pouvoir une choyer d'aucrée de compris le plus mite de genre, ce n'est pas moins)
Stalin est l'élection de la langie.

12

tu trouves pas que se trimballer des "this->" partout devant toutes tes variables membres c'est un poil lourd? #trihum#
je trouve pas ca plus lisible moi... grin (et en plus c'est plus chiant a ecrire, t'as plus de texte inutile dans ton code... bref... et c'est plus lourd a lire zzz a priori, la plupart du temps, lorsque tu lis du code ecrit par quelqu'un d'autre pour les premieres fois, l'information principale que tu cherches, c'est pas si telle ou telle variable est membre, locale, globale, passee en parametre, etc... c'est plutot ce que fait le code, les algos utilises, etc... pour comprendre la classe... donc la priorite c'est la lisibilite... c'est quoi le plus lisible, ca:
this->Pwet = dot(this->Position, FaceNormal) * this->PwetCoeff;
ou ca:
MPwet = dot(MPosition, faceNormal) * MPwetCoeff;
?
meme si l'exemple estsimpliste et que la premiere version saute quand meme aux yeux (mais plus la complexite augmentera plus l'ecart entre les deux sera important..), dans le deuxieme cas t'as pas a exclure les "this->" en lisant pour que l'operation effectuee te saute aux yeux et soit directement "lisible"... et apres, si tu veux savoir d'ou proviennent chacun des trucs utilises, t'as le prefixe... (genre, 'MTagadaTsointsoin' pour Member, rien pour des locales (tagadaTsointsoin), eventuellement "argTagadaTsointsoin" ou "parTagadaTsointsoin" pour les arguments/params de la fonction/methode, etc...))

donc, non, franchement, je trouve pas les "this" explicites particulierement lisibles... perso le seul cas ou j'utilise this, c'est pour passer un pointeur vers la classe a d'autres classes / fonctions...
avatar
HURRRR !

13

Pour les this, je fais assez souvent l'exemple donné par Kévin dans mes constructeurs, lorsque je me suis pas fatigué à utiliser une convention explicitant le statut d'une variables (eg: préfixe m_).

Cela dit il y a une autre explication, en ces temps troublés où des langages moisis sont - hélas - utilisés comme premier contact au développement par quelques malheureux développeurs. En PHP4, l'utilisation de $this est obligatoire, sinon ça fait référence à une variable locale.

14

spectras (./13) :
Cela dit il y a une autre explication, en ces temps troublés où des langages moisis sont - hélas - utilisés comme premier contact au développement par quelques malheureux développeurs. En PHP4, l'utilisation de $this est obligatoire, sinon ça fait référence à une variable locale.


Ce n'est que TON point de vue, et a mon avis il est bien plus sur d'utiliser this-> des que l'on veux acceder au contenu de la classe/objet que de permettre de le faire de maniere non préfixé.

Mais bon comme d'ab cette histoire n'est encore qu'une question de gouts et de couleurs. Chacun fait ce qu'il veux apres tout
avatar
Proud to be CAKE©®™


GCC4TI importe qui a problème en Autriche, pour l'UE plus et une encore de correspours nucléaire, ce n'est pas ytre d'instérier. L'état très même contraire, toujours reconstruire un pouvoir une choyer d'aucrée de compris le plus mite de genre, ce n'est pas moins)
Stalin est l'élection de la langie.

15

spectras: pas forcement que des langages moisis, on retrouve ca aussi en python love... (mais python simplement car les methodes sont ecrites explicitetement avec le pointeur en premier parametre:
class Foo:
  def plop(self, mystr):
    print mystr

)

godzil: heu... ca ajoute rien a la lisibilite, vraiment.

16

nEUrOO> c'est sensiblement différent, justement parce que self est un paramètre explicite, et pas un truc magique sorti de nulle part.
Godzil>
Ce n'est que TON point de vue, et a mon avis il est bien plus sur d'utiliser this-> des que l'on veux acceder au contenu de la classe/objet que de permettre de le faire de maniere non préfixé.
Sauf que c'est pas toujours équivalent.
class A {
    virtual int f();
}
class B : virtual A {
    virtual int f();
}
class C : B, virtual A {
    using A::f;
    void test() {
        f();        // Appelle A::f
        this->f();  // Appelle B::f
    }
}
Sauf erreur de déclaration, ça doit être ça en principe (merci de corriger l'exemple le cas échéant, ça fait super longtemps que j'ai pas remis le nez dedans, et chaque déclaration compte, quel héritage est virtuel, lequel ne l'est pas, ... pour arriver à ce résultat) ^^

17

Forcement tu met le doigt sur le fait que le C++ est une des pires implementation Objet qu'on puisse trouver...
avatar
Proud to be CAKE©®™


GCC4TI importe qui a problème en Autriche, pour l'UE plus et une encore de correspours nucléaire, ce n'est pas ytre d'instérier. L'état très même contraire, toujours reconstruire un pouvoir une choyer d'aucrée de compris le plus mite de genre, ce n'est pas moins)
Stalin est l'élection de la langie.

18

D'où l'intérêt d'appeler A::f() explicitement au lieu d'utiliser using qui bordélise encore plus le bordel qu'est déjà l'héritage multiple avec un nom de méthode en conflit.
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

19

(et puis vive l'héritage multiple sick)
avatar
Proud to be CAKE©®™


GCC4TI importe qui a problème en Autriche, pour l'UE plus et une encore de correspours nucléaire, ce n'est pas ytre d'instérier. L'état très même contraire, toujours reconstruire un pouvoir une choyer d'aucrée de compris le plus mite de genre, ce n'est pas moins)
Stalin est l'élection de la langie.

20

L'héritage multiple, quand utilisé bien à propos, est quelque chose de tout à fait propre. D'ailleurs, Java, si c'est à ça que tu pensais, l'a réintroduit dans sa version 1.5 si je ne m'abuse.
Evidemment, ça suppose de l'utiliser correctement (pour décrire une relation "ceci est un cela"), et non pas comme vu trop souvent juste pour récupérer du code...

21

spectras (./16) :
nEUrOO> c'est sensiblement différent, justement parce que self est un paramètre explicite, et pas un truc magique sorti de nulle part.
Godzil>
Ce n'est que TON point de vue, et a mon avis il est bien plus sur d'utiliser this-> des que l'on veux acceder au contenu de la classe/objet que de permettre de le faire de maniere non préfixé.
Sauf que c'est pas toujours équivalent.
class A {
    virtual int f();
}
class B : virtual A {
    virtual int f();
}
class C : B, virtual A {
    using A::f;
    void test() {
        f();        // Appelle A::f
        this->f();  // Appelle B::f
    }
}
Sauf erreur de déclaration, ça doit être ça en principe (merci de corriger l'exemple le cas échéant, ça fait super longtemps que j'ai pas remis le nez dedans, et chaque déclaration compte, quel héritage est virtuel, lequel ne l'est pas, ... pour arriver à ce résultat) ^^

moi qui voulait apprendre le c++ je sais même pas si je vais commencer avec ça fatigue

22

Ben... faut dire aussi, t'es pas obligé de faire des trucs à la con avec le langage. L'exemple là est quand même particulièrement tordu, et je doute que ce soit quelque chose qui puisse être utile dans une vraie application.

23

1 - Pour ce qui est du this-> : je le mets partout pour m'y retrouver c'est plus explicite pour moi. De toute façon le code généré n'en sera pas plus lourd. C'est mon vice, c'est comme ça. Et perso je préfère un this-> partout plutôt qu'une convention de nommage mal adaptée avec des noms de variables du genre hDlg ou lpCmdLine qui a tendance à me faire mal au yeux.
2 - Pour ce qui est du long long double : ok c'est peut-être un peut exagéré mais comme les calculs sont effectués avec un rayon de la Terre en mm je me suis dit qu'un flottant de 64 bits ne suffirait pas... m'enfin j'ai pas eu envie de vérifier j'ai laissé. Et puis si quelqu'un veut faire des calculs sur une planète autre que la Terre et qui a un rayon bien plus grand il ne se posera pas la question de savoir s'il n'est pas en dehors des limites, un flotant 128 bits devrait aller non?

Dans tous les cas comme le dit Godzil c'est une question de point de vue. Mon objectif étant de rendre l'utilisation de la classe la plus pratique possible.
Maintenant le code est sous GPLv2 donc si vous voulez ajouter quelque chose ou refaire à votre sauce ça sera avec grand plaisir.
Hormis les pov' 2h/semaine de VB durant l'IUT, j'ai appris tout seul et il y a certainement beaucoup à redire alors ne vous gênez pas.
spectras (./3) :
Faut dire, déjà le pow(distance, 2) fait peur.

Je n'ai pas trouvé de formule pour calculer la distance entre 2 coordonnées GPS lorsque les altitudes sont différentes. Je n'applique que Pythagore ici.

24

distance*distance est souvent mieux, apres, pour tes formules compliquees, tu peux souvent faire un developpement limite pour avoir moins de calculs lourds (au depend de la precision, mais bon... tu peux augmenter ton ordre).

128bits, calcule voire combien tu peux mettre dedans, tu verras que 64 c largement...

godzil: bah oui que l'objet en c++ est pas genial, c'est oriente...

25

nEUrOO (./24) :
distance*distance est souvent mieux, apres, pour tes formules compliquees, tu peux souvent faire un developpement limite pour avoir moins de calculs lourds (au depend de la precision, mais bon... tu peux augmenter ton ordre).

ok je vais remplacer les pow(X,2) par X*X
nEUrOO (./24) :
128bits, calcule voire combien tu peux mettre dedans, tu verras que 64 c largement...

je viens de voir qu'avec un long double la marge est de -3.4*10^-4932 à 3.4*10^4932 et 15 chiffres après la virgule. Ça devrait aller. happy

26

surtout que dans la plupart des GPS NMEA on obtient que des simples floats grin

27

Tout à fait mais tu confonds l'utilisation qui est faite du long double : c'est pour le calcul de distance.
Pour la déclaration des coordonnées c'est justement un float qui est utilisé :
Exemple pour les degrés décimales :
typedef struct
{
	short d;
	short m;
	float s;
}POINT_DMSd;



[pub]Je fais un parser NMEA aussi en ce moment[/pub]

28

ah, ok

[antipub]c'est pas spécialementune performance un parseur NMEA, à coup de regex on s'en sort assez rapidement[/antipub]

29

spomky (./27) :
Tout à fait mais tu confonds l'utilisation qui est faite du long double : c'est pour le calcul de distance.


hm, ca par exemple:

return (long long double)sqrt( pow((s.x - d.x),2) + pow((s.y - d.y),2) + pow((s.z - d.z),2));

tout ce que tu fais c'est caster le resultat en long long double...
sqrt et pow prennent et retournent des double simples... (sauf si tu les as overloadees et que tu as des versions qui fonctionnent avec des flottants 128 bits, ce dont je doute Oo)

donc tes calculs de distances la, ils sont faits en fp64, tout ce que tu fais c'est de caster le resultat (ie: ca sert a rien)
bon ceci dit j'ai pas tout regarde, mais la en tout cas, dans ce calcul de distance la, meme si tu castais le resultat final dans un flottant 4096 bits, tu n'aurais quand meme qu'une precision 64 bits.
avatar
HURRRR !

30

C'est simplement parce que j'ai oublié de virer le cast.
Je commit à nouveau.