OrbitePoints.java
001 package fr.isae.orbit;
002 
003 import fr.isae.geometry.Point;
004 import java.util.ArrayList;
005 
006 /**
007  <code>OrbitePoints</code> modelise une orbite elliptique autour de
008  * la Terre avec lancement a l'equateur (argument du perigee nul) sous
009  * forme d'une sequence de points. On peut translater l'orbite, lui
010  * appliquer une homothetie, calculer sa circonference et trouver une
011  * approximation d'un vecteur tangent en un point.
012  *
013  @author <a href="mailto:garion@isae.fr">Christophe Garion</a>
014  @version 1.0
015  */
016 public class OrbitePoints {
017 
018     private ArrayList<Point> points;
019     private Point centre;
020 
021     /**
022      * Creer une instance de <code>OrbitePoints</code> en utilisant
023      * une orbite definie geometriquement.
024      *
025      @param orbite l'orbite geometrique servant a calculer la
026      *               sequence de points
027      @param pasAngle le pas servant a incrementer l'angle pour
028      *                 le calcul des points
029      */
030     public OrbitePoints(Orbite orbite, double pasAngle) {
031         this.points = new ArrayList<Point>();
032 
033         for (double angle = 0.0;
034              angle < 2.0 * Math.PI;
035              angle += pasAngle) {
036             this.points.add(orbite.calculerPointSurOrbite(angle));
037         }
038 
039         this.centre = orbite.getFoyer();
040         this.centre.translater(-orbite.getC()0.0);
041     }
042 
043     private OrbitePoints(ArrayList<Point> points, Point centre) {
044         this.points = new ArrayList<Point>();
045 
046         for (Point p: points) {
047             this.points.add(p.clone());
048         }
049 
050         this.centre = centre.clone();
051     }
052 
053     /**
054      * Le nombre de points contenu dans l'orbite.
055      *
056      @return le nombre de points stockes
057      */
058     public int getNbPoints() {
059         return this.points.size();
060     }
061 
062     /**
063      * Retourner un point de l'orbite.
064      *
065      @param i un index, compris entre <code>1</code> et
066      *          <code>this.getNbPoints()</code>
067      @return le ieme point dans la sequence
068      */
069     public Point getPoint(int i) {
070         return this.points.get(i - 1).clone();
071     }
072 
073     /**
074      * Retourner le centre de l'orbite.
075      *
076      @return une instance de <code>Point</code> qui est egale
077      *         au centre de l'orbite. Il s'agit d'une copie et
078      *         non pas d'une reference vers le point stocke
079      */
080     public Point getCentre() {
081         return this.centre.clone();
082     }
083 
084     /**
085      * Retourner une approximation de la circonference de l'ellipse.
086      *
087      @return une approximation de la circonference de l'ellipse
088      *         calculee en utilisant le perimetre du polygone forme
089      *         par les points
090      */
091     public double getCirconference() {
092         double c = 0;
093 
094         for (int i = 1; i <= this.getNbPoints() 1; i++) {
095             c += this.getPoint(i).distance(this.getPoint(i + 1));
096         }
097 
098         c += this.getPoint(this.getNbPoints()).distance(this.getPoint(1));
099 
100         return c;
101     }
102 
103     /**
104      * Retourner une approximation du vecteur tangent en un point.
105      * On utilise le vecteur forme par le point precedent et le point
106      * suivant dans la liste de points. Le vecteur tangent renvoye est
107      * normalise.
108      *
109      @param i un index, compris entre <code>1</code> et
110      *          <code>this.getNbPoints()</code>
111      @return une approximation du vecteur tangent
112      */
113     public Point getVecteurTangent(int i) {
114         Point precedent;
115         Point suivant;
116 
117         if (i == 1) {
118             precedent = this.points.get(this.points.size() 1);
119         else {
120             precedent = this.points.get(i - 2);
121         }
122 
123         if (i == this.points.size()) {
124             suivant = this.points.get(0);
125         else {
126             suivant = this.points.get(i);
127         }
128 
129         Point vecteur = new Point(suivant.getX() - precedent.getX(),
130                                   suivant.getY() - precedent.getY());
131         double longueur = vecteur.getModule();
132 
133         vecteur.setX(vecteur.getX() / longueur);
134         vecteur.setY(vecteur.getY() / longueur);
135 
136         return vecteur;
137     }
138 
139     /**
140      * Translater l'orbite. Les points de l'orbite et le centre sont
141      * translates.
142      *
143      @param dx l'abscisse du vecteur de translation
144      @param dy l'ordonnee du vecteur de translation
145      */
146     public void translater(double dx, double dy) {
147         for (Point p: this.points) {
148             p.translater(dx, dy);
149         }
150 
151         this.centre.translater(dx, dy);
152     }
153 
154     /**
155      * Appliquer une homothetie a l'orbite. L'homothetie est effectuee
156      * par rapport au centre de l'ellipse.
157      *
158      @param rapport le rapport d'homothetie
159      */
160     public void homothetie(double rapport) {
161         this.translater(-centre.getX(), -centre.getY());
162 
163         // on effectue l'homothetie
164         for (Point p: this.points) {
165             p.setModule(p.getModule() * rapport);
166         }
167 
168         this.translater(centre.getX(), centre.getY());
169     }
170 
171     /**
172      * Verifier si deux orbites sont egales. Pour cela on verifie qu'elles
173      * ont le meme nombre de points, que tous leurs points sont egaux (au
174      * sens de <code>equals</code>) et que leurs centres sont egaux.
175      *
176      @param o l'orbite dont on veut verifier si elle est egale a
177      *          <code>this</code>
178      @return un booleen qui est <code>true</code> si les deux orbites
179      *         sont egales
180      */
181     public boolean equals(OrbitePoints o) {
182         if (this.points.size() != o.points.size()) {
183             return false;
184         }
185 
186         if (!this.centre.equals(o.centre)) {
187             return false;
188         }
189 
190         for (int i = 0; i < this.points.size(); i++) {
191             if (!this.points.get(i).equals(o.points.get(i))) {
192                 return false;
193             }
194         }
195 
196         return true;
197     }
198 
199     /**
200      * Cloner une orbite. L'orbite obtenue est un objet different, mais est
201      * egale a <code>this</code>.
202      *
203      @return un clone de <code>this</code>
204      */
205     public OrbitePoints clone() {
206         return new OrbitePoints(this.points, this.centre);
207     }
208 
209     /**
210      * Representer l'orbite sous forme d'une chaine de caracteres. On affiche
211      * le centre de l'orbite puis 10 points parmi l'ensemble de points de
212      * l'orbite.
213      *
214      @return une instance de <code>String</code> representant l'orbite
215      */
216     public String toString() {
217         String s = "centre : " this.centre + "\n[";
218 
219         int step = this.points.size() 10;
220 
221         for (int i = 0; i < 10; i++) {
222             s += this.points.get(i * step(i == "\n]" " ...\n");
223         }
224 
225         return s + "]";
226     }
227 }