001: /*
002: * This file is part of the GeOxygene project source files.
003: *
004: * GeOxygene aims at providing an open framework which implements OGC/ISO specifications for
005: * the development and deployment of geographic (GIS) applications. It is a open source
006: * contribution of the COGIT laboratory at the Institut Géographique National (the French
007: * National Mapping Agency).
008: *
009: * See: http://oxygene-project.sourceforge.net
010: *
011: * Copyright (C) 2005 Institut Géographique National
012: *
013: * This library is free software; you can redistribute it and/or modify it under the terms
014: * of the GNU Lesser General Public License as published by the Free Software Foundation;
015: * either version 2.1 of the License, or any later version.
016: *
017: * This library is distributed in the hope that it will be useful, but WITHOUT ANY
018: * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
019: * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
020: *
021: * You should have received a copy of the GNU Lesser General Public License along with
022: * this library (see file LICENSE if present); if not, write to the Free Software
023: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
024: *
025: */
026:
027: package fr.ign.cogit.geoxygene.contrib.geometrie;
028:
029: import fr.ign.cogit.geoxygene.spatial.coordgeom.DirectPosition;
030:
031: /**
032: * Classe des angles en radian. Supporte quelques opérations
033: * de base.
034: * La classe possede un attribut angle qui est la valeur de l'angle (en radians)
035: * comprise entre 0 et 2*pi. La methode setAngle(a) ramene a entre en 0 et 2*pi.
036: *
037: * English: Class for computations on angles (in radian). The attribute
038: * angle is the value of the angle (in radian) between 0 and 2*pi.
039: *
040: * @author Mustière/Bonin/Grosso
041: * @version 1.0
042: */
043:
044: public class Angle {
045: // CONSTANTES
046: /** angle de valeur nulle */
047: public static final Angle angleNul = new Angle(0);
048: /** angle de valeur PI */
049: public static final Angle anglePlat = new Angle(Math.PI);
050: /** angle de valeur PI/2 */
051: public static final Angle angleDroit = new Angle(Math.PI / 2);
052:
053: /** NE PAS UTILISER: utiliser plutot Math.PI
054: * @deprecated */
055: public static final double pi = Math.PI;
056:
057: protected double angle = 0;
058:
059: public double getAngle() {
060: return this .angle;
061: }
062:
063: public void setAngle(double valeur) {
064: if (valeur % (2 * Math.PI) >= 0)
065: this .angle = Math.abs(valeur % (2 * Math.PI));
066: else
067: this .angle = (valeur % (2 * Math.PI) + 2 * Math.PI);
068: }
069:
070: /* Constructeurs */
071: public Angle() {
072: }
073:
074: public Angle(double valeur) {
075: this .setAngle(valeur);
076: }
077:
078: /** Angle entre 2 points dans le plan X,Y (valeur comprise entre 0 et 2*pi) */
079: public Angle(DirectPosition pt1, DirectPosition pt2) {
080: double x = pt2.getX() - pt1.getX();
081: double y = pt2.getY() - pt1.getY();
082: this .setAngle(Math.atan2(y, x));
083: }
084:
085: /** Crée un angle à pi près (entre O et pi),
086: * à partir d'un angle à 2pi près (entre 0 et pi) */
087: public static Angle angleAPiPres(Angle angle2pi) {
088: if (angle2pi.angle > Math.PI)
089: return new Angle(angle2pi.angle - Math.PI);
090: return new Angle(angle2pi.angle);
091: }
092:
093: /** Crée un angle à pi près (entre O et pi),
094: * à partir de this */
095: public Angle angleAPiPres() {
096: if (this .angle > Math.PI)
097: return new Angle(this .angle - Math.PI);
098: return new Angle(this .angle);
099: }
100:
101: /** ajoute a à l'angle */
102: public void ajoute(Angle a) {
103: this .setAngle(this .angle + a.angle);
104: }
105:
106: /** ajoute les angles a et b */
107: public static Angle ajoute(Angle a, Angle b) {
108: return new Angle(a.angle + b.angle);
109: }
110:
111: /** Angle de la "bissectrice" des deux angles a et b.
112: * L'angle est au milieu entre a et b.
113: * NB: bissectrice(a,b) = bissectrice(b,a) + PI */
114: public static Angle bissectrice(Angle a, Angle b) {
115: return new Angle(a.angle + ecarttrigo(a, b).angle / 2);
116: }
117:
118: /** Moyenne de deux angles (défini à pi près). */
119: public static Angle moyenne(Angle a, Angle b) {
120: return angleAPiPres(new Angle((a.angle + b.angle) / 2));
121: }
122:
123: /** Ecart de a vers b dans le sens trigonométrique,
124: * ex : ecart(pi/4, 7pi/4) = 3pi/2 */
125: public static Angle ecarttrigo(Angle a, Angle b) {
126: return new Angle(b.angle - a.angle);
127: }
128:
129: /** Ecart au plus court entre les deux angles,
130: * dans [0,pi], ex : ecart(pi/4, 7pi/4) = pi/2 */
131: public static Angle ecart(Angle a, Angle b) {
132: return new Angle(Math.min(ecarttrigo(a, b).getAngle(),
133: ecarttrigo(b, a).getAngle()));
134: }
135:
136: /** Angle entre 3 points; pt2 est le point central: angle(pt2pt1,pt2pt3). */
137: public static Angle angleTroisPoints(DirectPosition pt1,
138: DirectPosition pt2, DirectPosition pt3) {
139: Angle angle1 = new Angle(pt2, pt1);
140: Angle angle2 = new Angle(pt2, pt3);
141: Angle angle = Angle.ecarttrigo(angle1, angle2);
142: return angle;
143: }
144: }
|