source: 2013/30/MiskaK/MW2(My Warfare 2)/Paranneltu Jypeli/DataTypes/UnlimitedAngle.cs @ 4507

Revision 4507, 15.1 KB checked in by anlakane, 6 years ago (diff)

Talletus.

Line 
1#region MIT License
2/*
3 * Copyright (c) 2009 University of Jyväskylä, Department of Mathematical
4 * Information Technology.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24#endregion
25
26/*
27 * Authors: Tero Jäntti, Tomi Karppinen, Janne Nikkanen.
28 */
29
30using System;
31using AdvanceMath;
32using System.Globalization;
33
34namespace Jypeli
35{
36    /// <summary>
37    /// Rajoittamaton kulma (asteina ja radiaaneina).
38    /// Tietoja kulmasta: http://en.wikipedia.org/wiki/File:Degree-Radian_Conversion.svg
39    /// </summary>
40    public struct UnlimitedAngle
41    {
42        /// <summary>
43        /// Nollakulma.
44        /// </summary>
45        public static readonly UnlimitedAngle Zero = new UnlimitedAngle( 0 );
46
47        /// <summary>
48        /// Suora kulma (90 astetta).
49        /// </summary>
50        public static readonly UnlimitedAngle RightAngle = new UnlimitedAngle( 0.5 * Math.PI );
51
52        /// <summary>
53        /// Oikokulma (180 astetta).
54        /// </summary>
55        public static readonly UnlimitedAngle StraightAngle = new UnlimitedAngle( Math.PI );
56
57        /// <summary>
58        /// Täysikulma (360 astetta).
59        /// </summary>
60        public static readonly UnlimitedAngle FullAngle = new UnlimitedAngle( 2 * Math.PI );
61
62        private double radian;
63
64        /// <summary>
65        /// Palauttaa tai asettaa kulman asteina.
66        /// </summary>
67        /// <value>Asteet.</value>
68        public double Degrees
69        {
70            get
71            {
72                return RadianToDegree( radian );
73            }
74            set
75            {
76                radian = DegreeToRadian( value );
77            }
78        }
79
80        /// <summary>
81        /// Palauttaa tai asettaa kulman radiaaneina.
82        /// </summary>
83        /// <value>Radiaanit.</value>
84        public double Radians
85        {
86            get { return radian; }
87            set
88            {
89                radian = (float)value; 
90            }
91        }
92
93        /// <summary>
94        /// Kulmaa vastaava pääilmansuunta.
95        /// </summary>
96        public Direction MainDirection
97        {
98            get
99            {
100                if ( radian >= -Math.PI / 4 && radian <= Math.PI / 4 ) return Direction.Right;
101                if ( radian > Math.PI / 4 && radian < 3 * Math.PI / 4 ) return Direction.Up;
102                if ( radian < -Math.PI / 4 && radian > -3 * Math.PI / 4 ) return Direction.Down;
103                return Direction.Left;
104            }
105        }
106
107        /// <summary>
108        /// Kulman sini.
109        /// </summary>
110        public double Sin
111        {
112            get { return Math.Sin( this.Radians ); }
113        }
114
115        /// <summary>
116        /// Kulman kosini.
117        /// </summary>
118        public double Cos
119        {
120            get { return Math.Cos( this.Radians ); }
121        }
122
123        /// <summary>
124        /// Kulman tangentti.
125        /// </summary>
126        public double Tan
127        {
128            get { return Math.Tan( this.Radians ); }
129        }
130
131
132        private UnlimitedAngle( double radians )
133        {
134            this.radian = (float)radians;
135        }
136
137        #region Operators
138
139        /// <summary>
140        /// Laskee kaksi kulmaa yhteen.
141        /// </summary>
142        /// <param name="a">Kulma.</param>
143        /// <param name="b">Kulma.</param>
144        /// <returns>Kulmien summa.</returns>
145        public static UnlimitedAngle operator +( UnlimitedAngle a, UnlimitedAngle b )
146        {
147            return FromRadians( a.Radians + b.Radians );
148        }
149
150        /// <summary>
151        /// Vähentää jälkimmäisen kulman ensimmäisestä.
152        /// </summary>
153        /// <param name="a">Kulma.</param>
154        /// <param name="b">Kulma.</param>
155        /// <returns>Kulmien erotus.</returns>
156        public static UnlimitedAngle operator -( UnlimitedAngle a, UnlimitedAngle b )
157        {
158            return FromRadians( a.Radians - b.Radians );
159        }
160
161        /// <summary>
162        /// Ottaa kulman vastakulman.
163        /// </summary>
164        /// <param name="a">Kulma.</param>
165        public static UnlimitedAngle operator -( UnlimitedAngle a )
166        {
167            return FromRadians( -a.Radians );
168        }
169
170        /// <summary>
171        /// Kertoo kulman reaaliluvulla.
172        /// </summary>
173        /// <param name="a">Reaaliluku.</param>
174        /// <param name="b">Kulma.</param>
175        /// <returns>Kulma.</returns>
176        public static UnlimitedAngle operator *( double a, UnlimitedAngle b )
177        {
178            return FromRadians( a * b.Radians );
179        }
180
181        /// <summary>
182        /// Kertoo kulman reaaliluvulla.
183        /// </summary>
184        /// <param name="a">Kulma.</param>
185        /// <param name="b">Reaaliluku.</param>
186        /// <returns>Kulma.</returns>
187        public static UnlimitedAngle operator *( UnlimitedAngle a, double b )
188        {
189            return FromRadians( a.Radians * b );
190        }
191
192        /// <summary>
193        /// Jakaa kulman reaaliluvulla.
194        /// </summary>
195        /// <param name="a">Kulma.</param>
196        /// <param name="b">Reaaliluku.</param>
197        /// <returns>Kulma.</returns>
198        public static UnlimitedAngle operator /( UnlimitedAngle a, double b )
199        {
200            return FromRadians( a.Radians / b );
201        }
202
203        /// <summary>
204        /// Vertaa kahden kulman yhtäsuuruutta.
205        /// </summary>
206        /// <param name="a">Kulma.</param>
207        /// <param name="b">Kulma.</param>
208        /// <returns>Yhtäsuuruus.</returns>
209        public static bool operator ==( UnlimitedAngle a, UnlimitedAngle b )
210        {
211            return a.Radians == b.Radians;
212        }
213
214        /// <summary>
215        /// Vertaa kahden kulman erisuuruutta.
216        /// </summary>
217        /// <param name="a">Kulma.</param>
218        /// <param name="b">Kulma.</param>
219        /// <returns>Erisuuruus.</returns>
220        public static bool operator !=( UnlimitedAngle a, UnlimitedAngle b )
221        {
222            return a.Radians != b.Radians;
223        }
224
225        /// <summary>
226        /// Vertaa ensimmäisen kulman suuremmuutta toiseen.
227        /// </summary>
228        /// <param name="a">Kulma.</param>
229        /// <param name="b">Kulma.</param>
230        /// <returns><c>true</c> jos suurempi, <c>false</c> jos pienempi tai yhtäsuuri.</returns>
231        public static bool operator <( UnlimitedAngle a, UnlimitedAngle b )
232        {
233            return a.Radians < b.Radians;
234        }
235
236        /// <summary>
237        /// Vertaa ensimmäisen kulman suuremmuutta/yhtäsuuruutta toiseen.
238        /// </summary>
239        /// <param name="a">Kulma.</param>
240        /// <param name="b">Kulma.</param>
241        /// <returns><c>true</c> jos suurempi tai yhtäsuuri, <c>false</c> jos pienempi.</returns>
242        public static bool operator <=( UnlimitedAngle a, UnlimitedAngle b )
243        {
244            return a.Radians <= b.Radians;
245        }
246
247        /// <summary>
248        /// Vertaa ensimmäisen kulman pienemmyyttä toiseen.
249        /// </summary>
250        /// <param name="a">Kulma.</param>
251        /// <param name="b">Kulma.</param>
252        /// <returns><c>true</c> jos pienempi, <c>false</c> jos suurempi tai yhtäsuuri.</returns>
253        public static bool operator >( UnlimitedAngle a, UnlimitedAngle b )
254        {
255            return a.Radians > b.Radians;
256        }
257
258        /// <summary>
259        /// Vertaa ensimmäisen kulman pienemmyyttä/yhtäsuuruutta toiseen.
260        /// </summary>
261        /// <param name="a">Kulma.</param>
262        /// <param name="b">Kulma.</param>
263        /// <returns><c>true</c> jos pienempi tai yhtäsuuri, <c>false</c> jos suurempi.</returns>
264        public static bool operator >=( UnlimitedAngle a, UnlimitedAngle b )
265        {
266            return a.Radians >= b.Radians;
267        }
268
269        /// <summary>
270        /// Rajoittaa kulman tyyppimuunnoksena.
271        /// </summary>
272        /// <param name="angle">Rajoittamaton kulma</param>
273        /// <returns>Rajoitettu kulma</returns>
274        public static explicit operator Angle( UnlimitedAngle angle )
275        {
276            return angle.Limit();
277        }
278
279        /// <summary>
280        /// Laskee yhteen rajoittamattoman ja rajoitetun kulman, palauttaen rajoittamattoman kulman.
281        /// </summary>
282        /// <param name="a">Rajoittamaton kulma</param>
283        /// <param name="b">Rajoitettu kulma</param>
284        /// <returns>Rajoittamaton kulma</returns>
285        public static UnlimitedAngle Sum( UnlimitedAngle a, Angle b )
286        {
287            return UnlimitedAngle.FromRadians( a.Radians + b.Radians );
288        }
289
290        /// <summary>
291        /// Laskee yhteen rajoitetun ja rajoittamattoman kulman, palauttaen rajoittamattoman kulman.
292        /// </summary>
293        /// <param name="a">Rajoitettu kulma</param>
294        /// <param name="b">Rajoittamaton kulma</param>
295        /// <returns>Rajoittamaton kulma</returns>
296        public static UnlimitedAngle Sum( Angle a, UnlimitedAngle b )
297        {
298            return UnlimitedAngle.FromRadians( a.Radians + b.Radians );
299        }
300
301        #endregion
302
303        /// <summary>
304        /// Palauttaa kulman rajoitettuna välille -180 ja 180 astetta.
305        /// </summary>
306        public Angle Limit()
307        {
308            return Angle.FromRadians( this.radian );
309        }
310
311        /// <summary>
312        /// Luo kulman annettujen radiaanien mukaan.
313        /// </summary>
314        /// <param name="radian">Radiaanit.</param>
315        public static UnlimitedAngle FromRadians( double radian )
316        {
317            return new UnlimitedAngle( radian );
318        }
319
320        /// <summary>
321        /// Luo kulman annettujen asteiden mukaan.
322        /// </summary>
323        /// <param name="degree">Asteet.</param>
324        public static UnlimitedAngle FromDegrees( double degree )
325        {
326            return new UnlimitedAngle( DegreeToRadian( degree ) );
327        }
328
329        /// <summary>
330        /// Muuttaa asteet radiaaneiksi.
331        /// </summary>
332        /// <param name="degree">Asteet.</param>
333        /// <returns></returns>
334        public static double DegreeToRadian( double degree )
335        {
336            return (float)(degree * ( System.Math.PI / 180 ));
337        }
338
339        /// <summary>
340        /// Muuttaa radiaanit asteiksi.
341        /// </summary>
342        /// <param name="radian">Radiaanit.</param>
343        /// <returns></returns>
344        public static double RadianToDegree( double radian )
345        {
346            return radian * ( 180 / Math.PI );
347        }
348
349        /// <summary>
350        /// Palauttaa kulmaa yksilöivän luvun, tässä tapauksessa kulman asteluvun.
351        /// </summary>
352        /// <returns>
353        /// Kokonaisluku.
354        /// </returns>
355        public override int GetHashCode()
356        {
357            return Convert.ToInt32( Degrees );
358        }
359
360        /// <summary>
361        /// Tarkistaa kahden kulman yhtäsuuruuden. Jos parametrinä annetaan jotain muuta kuin kulma, tulos on aina epätosi.
362        /// </summary>
363        /// <param name="obj">Toinen kulma.</param>
364        /// <returns></returns>
365        public override bool Equals( object obj )
366        {
367            if ( obj is UnlimitedAngle )
368            {
369                return Double.Equals( this.Radians, ( (UnlimitedAngle)obj ).Radians );
370            }
371
372            else if ( obj is Angle )
373            {
374                return Double.Equals( this.Radians, ( (Angle)obj ).Radians );
375            }
376
377            return false;
378        }
379
380        public override string ToString()
381        {
382            return radian.ToString( System.Globalization.NumberFormatInfo.InvariantInfo );
383        }
384
385        public string ToString( IFormatProvider formatProvider )
386        {
387            return radian.ToString( formatProvider );
388        }
389
390        public static UnlimitedAngle Parse( string angleStr, IFormatProvider formatProvider )
391        {
392            return new UnlimitedAngle( double.Parse( angleStr, formatProvider ) );
393        }
394
395        public static UnlimitedAngle Parse( string angleStr )
396        {
397            return new UnlimitedAngle( double.Parse( angleStr, NumberFormatInfo.InvariantInfo ) );
398        }
399
400        /// <summary>
401        /// Palauttaa kulman radiaaneina siten, että se on aina positiivinen.
402        /// Hyödyllinen esimerkiksi ympyrän kaarien käsittelyssä.
403        /// </summary>
404        /// <returns>]0,2pi]</returns>
405        public double GetPositiveRadians()
406        {
407            return Radians > 0 ? Radians : Math.PI * 2 + Radians;
408        }
409
410        /// <summary>
411        /// Palauttaa kulman asteina siten, että se on aina positiivinen.
412        /// Hyödyllinen esimerkiksi ympyrän kaarien käsittelyssä.
413        /// </summary>
414        /// <returns>]0,360]</returns>
415        public double GetPositiveDegrees()
416        {
417            double deg = Degrees;
418            while ( deg < 0 ) deg += 360;
419            return deg;
420        }
421
422        public Vector GetVector()
423        {
424            return Vector.FromAngle( Limit() );
425        }
426
427        #region Arcusfunktiot
428
429        /// <summary>
430        /// Palauttaa kulman joka vastaa d:n arcus-sini.
431        /// </summary>
432        /// <param name="d">Lukuarvo välillä 0-1.</param>
433        /// <returns>Kulma.</returns>
434        public static UnlimitedAngle ArcSin( double d )
435        {
436            return new UnlimitedAngle( Math.Asin( d ) );
437        }
438
439        /// <summary>
440        /// Palauttaa kulman joka vastaa d:n arcuskosini.
441        /// </summary>
442        /// <param name="d">Lukuarvo välillä 0-1.</param>
443        /// <returns>Kulma.</returns>
444        public static UnlimitedAngle ArcCos( double d )
445        {
446            return new UnlimitedAngle( Math.Acos( d ) );
447        }
448
449        /// <summary>
450        /// Palauttaa kulman joka vastaa d:n arcus-tangentti.
451        /// </summary>
452        /// <param name="d">Lukuarvo.</param>
453        /// <returns>Kulma.</returns>
454        public static UnlimitedAngle ArcTan( double d )
455        {
456            return new UnlimitedAngle( Math.Atan( d ) );
457        }
458
459        #endregion
460    }
461}
Note: See TracBrowser for help on using the repository browser.