3 * Iter Vehemens ad Necem (IVAN)
4 * Copyright (C) Timo Kiviluoto
5 * Released under the GNU General
8 * See LICENSING which should be included
9 * along with this file for more details
19 cint
basequadricontroller::OrigoDeltaX
[4] = { 0, 1, 0, 1 };
20 cint
basequadricontroller::OrigoDeltaY
[4] = { 0, 0, 1, 1 };
21 int basequadricontroller::OrigoX
, basequadricontroller::OrigoY
;
22 int basequadricontroller::StartX
, basequadricontroller::StartY
;
23 int basequadricontroller::XSize
, basequadricontroller::YSize
;
24 int basequadricontroller::RadiusSquare
;
25 truth
basequadricontroller::SectorCompletelyClear
;
28 /* A C-program for MT19937: Integer version */
29 /* genrand() generates one pseudorandom unsigned integer (32bit) */
30 /* which is uniformly distributed among 0 to 2^32-1 for each */
31 /* call. sgenrand(seed) set initial values to the working area */
32 /* of 624 words. Before genrand(), sgenrand(seed) must be */
33 /* called once. (seed is any 32-bit integer except for 0). */
34 /* Coded by Takuji Nishimura, considering the suggestions by */
35 /* Topher Cooper and Marc Rieffel in July-Aug. 1997. */
37 /* This library is free software; you can redistribute it and/or */
38 /* modify it under the terms of the GNU Library General Public */
39 /* License as published by the Free Software Foundation; either */
40 /* version 2 of the License, or (at your option) any later */
42 /* This library is distributed in the hope that it will be useful, */
43 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
44 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */
45 /* See the GNU Library General Public License for more details. */
46 /* You should have received a copy of the GNU Library General */
47 /* Public License along with this library; if not, write to the */
48 /* Free Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA */
51 /* Copyright (C) 1997 Makoto Matsumoto and Takuji Nishimura. */
52 /* Any feedback is very welcome. For any question, comments, */
53 /* see http://www.math.keio.ac.jp/matumoto/emt.html or email */
54 /* matumoto@math.keio.ac.jp */
56 /* Period parameters */
59 #define MATRIX_A 0x9908b0df /* constant vector a */
60 #define UPPER_MASK 0x80000000 /* most significant w-r bits */
61 #define LOWER_MASK 0x7fffffff /* least significant r bits */
63 /* Tempering parameters */
64 #define TEMPERING_MASK_B 0x9d2c5680
65 #define TEMPERING_MASK_C 0xefc60000
66 #define TEMPERING_SHIFT_U(y) (y >> 11)
67 #define TEMPERING_SHIFT_S(y) (y << 7)
68 #define TEMPERING_SHIFT_T(y) (y << 15)
69 #define TEMPERING_SHIFT_L(y) (y >> 18)
71 uLong
femath::mt
[N1
]; /* the array for the state vector */
72 sLong
femath::mti
= N1
+1; /* mti==N+1 means mt[N] is not initialized */
76 uLong
femath::mtb
[N1
];
79 void femath::SetSeed (uLong Seed
) {
80 /* setting initial seeds to mt[N] using */
81 /* the generator Line 25 of Table 1 in */
82 /* [KNUTH 1981, The Art of Computer Programming */
83 /* Vol. 2 (2nd Ed.), pp102] */
84 mt
[0] = Seed
& 0xffffffff;
85 for (mti
=1; mti
< N1
; mti
++) mt
[mti
] = (69069*mt
[mti
-1])&0xffffffff;
89 sLong
femath::Rand () {
91 static uLong mag01
[2]={0x0, MATRIX_A
};
93 /* mag01[x] = x * MATRIX_A for x=0,1 */
95 if (mti
>= N1
) { /* generate N words at one time */
98 if (mti
== N1
+1) /* if sgenrand() has not been called, */
99 SetSeed(4357); /* a default initial seed is used */
101 for (kk
=0;kk
<N1
-M
;kk
++) {
102 y
= (mt
[kk
]&UPPER_MASK
)|(mt
[kk
+1]&LOWER_MASK
);
103 mt
[kk
] = mt
[kk
+M
] ^ (y
>> 1) ^ mag01
[y
& 0x1];
105 for (;kk
<N1
-1;kk
++) {
106 y
= (mt
[kk
]&UPPER_MASK
)|(mt
[kk
+1]&LOWER_MASK
);
107 mt
[kk
] = mt
[kk
+(M
-N1
)] ^ (y
>> 1) ^ mag01
[y
& 0x1];
109 y
= (mt
[N1
-1]&UPPER_MASK
)|(mt
[0]&LOWER_MASK
);
110 mt
[N1
-1] = mt
[M
-1] ^ (y
>> 1) ^ mag01
[y
& 0x1];
116 y
^= TEMPERING_SHIFT_U(y
);
117 y
^= TEMPERING_SHIFT_S(y
) & TEMPERING_MASK_B
;
118 y
^= TEMPERING_SHIFT_T(y
) & TEMPERING_MASK_C
;
119 y
^= TEMPERING_SHIFT_L(y
);
121 return y
& 0x7FFFFFFF;
125 int femath::WeightedRand (sLong
*Possibility
, sLong TotalPossibility
) {
126 sLong Rand
= RAND()%TotalPossibility
, PartialSum
= 0;
127 for (int c
= 0; ; ++c
) {
128 PartialSum
+= Possibility
[c
];
129 if (PartialSum
> Rand
) return c
;
134 int femath::WeightedRand (const std::vector
<sLong
> &Possibility
, sLong TotalPossibility
) {
135 sLong Rand
= RAND()%TotalPossibility
, PartialSum
= 0;
136 for (int c
= 0;; ++c
) {
137 PartialSum
+= Possibility
[c
];
138 if (PartialSum
> Rand
) return c
;
143 double femath::CalculateAngle(v2 Direction
) {
144 if (Direction
.X
< 0) return atan(double(Direction
.Y
)/Direction
.X
)+FPI
;
145 if (Direction
.X
> 0) {
146 if (Direction
.Y
< 0) return atan(double(Direction
.Y
)/Direction
.X
)+2*FPI
;
147 return atan(double(Direction
.Y
)/Direction
.X
);
149 if (Direction
.Y
< 0) return 3*FPI
/2;
150 if (Direction
.Y
> 0) return FPI
/2;
151 ABORT("Illegal direction (0, 0) passed to femath::CalculateAngle()!");
156 void femath::CalculateEnvironmentRectangle (rect
&Rect
, const rect
&MotherRect
, v2 Origo
, int Radius
) {
157 Rect
.X1
= Origo
.X
-Radius
;
158 Rect
.Y1
= Origo
.Y
-Radius
;
159 Rect
.X2
= Origo
.X
+Radius
;
160 Rect
.Y2
= Origo
.Y
+Radius
;
161 if (Rect
.X1
< MotherRect
.X1
) Rect
.X1
= MotherRect
.X1
;
162 if (Rect
.Y1
< MotherRect
.Y1
) Rect
.Y1
= MotherRect
.Y1
;
163 if (Rect
.X2
> MotherRect
.X2
) Rect
.X2
= MotherRect
.X2
;
164 if (Rect
.Y2
> MotherRect
.Y2
) Rect
.Y2
= MotherRect
.Y2
;
168 truth
femath::Clip (int &SourceX
, int &SourceY
, int &DestX
, int &DestY
, int &Width
, int &Height
, int XSize
, int YSize
, int DestXSize
, int DestYSize
) {
169 /* This sentence is usually true */
170 if (SourceX
>= 0 && SourceY
>= 0 && DestX
>= 0 && DestY
>= 0 &&
171 SourceX
+Width
<= XSize
&& SourceY
+Height
<= YSize
&&
172 DestX
+Width
<= DestXSize
&& DestY
+Height
<= DestYSize
) return true;
193 if (SourceX
+Width
> XSize
) Width
= XSize
-SourceX
;
194 if (SourceY
+Height
> YSize
) Height
= YSize
-SourceY
;
195 if (DestX
+Width
> DestXSize
) Width
= DestXSize
-DestX
;
196 if (DestY
+Height
> DestYSize
) Height
= DestYSize
-DestY
;
197 return Width
>0 && Height
>0;
201 void femath::SaveSeed () {
203 for (int c
= 0; c
< N1
; ++c
) mtb
[c
] = mt
[c
];
207 void femath::LoadSeed () {
209 for (int c
= 0; c
< N1
; ++c
) mt
[c
] = mtb
[c
];
213 void ReadData(interval
&I
, inputfile
&SaveFile
) {
214 I
.Min
= SaveFile
.ReadNumber(HIGHEST
, true);
216 SaveFile
.ReadWord(Word
);
217 if (Word
== ";" || Word
== ",") I
.Max
= I
.Min
;
218 else if (Word
== ":") I
.Max
= Max(SaveFile
.ReadNumber(), I
.Min
);
219 else ABORT("Odd interval terminator %s detected, file %s line %d!", Word
.CStr(), SaveFile
.GetFileName().CStr(), SaveFile
.TellLine());
223 void ReadData (region
&R
, inputfile
&SaveFile
) {
224 ReadData(R
.X
, SaveFile
);
225 ReadData(R
.Y
, SaveFile
);
229 outputfile
&operator << (outputfile
&SaveFile
, const interval
&I
) {
230 SaveFile
.Write(reinterpret_cast<cchar
*>(&I
), sizeof(I
));
235 inputfile
&operator >> (inputfile
&SaveFile
, interval
&I
) {
236 SaveFile
.Read(reinterpret_cast<char *>(&I
), sizeof(I
));
241 outputfile
&operator << (outputfile
&SaveFile
, const region
&R
) {
242 SaveFile
.Write(reinterpret_cast<cchar
*>(&R
), sizeof(R
));
247 inputfile
&operator >> (inputfile
&SaveFile
, region
&R
) {
248 SaveFile
.Read(reinterpret_cast<char *>(&R
), sizeof(R
));
253 sLong
femath::SumArray (const fearray
<sLong
> &Vector
) {
255 for (uInt c
= 0; c
< Vector
.Size
; ++c
) Sum
+= Vector
.Data
[c
];
260 void femath::GenerateFractalMap (int **Map
, int Side
, int StartStep
, int Randomness
) {
265 Map
[Limit
][Limit
] = 0;
266 for (int Step
= StartStep
, HalfStep
= Step
>>1; HalfStep
;
267 Step
= HalfStep
, HalfStep
>>=1, Randomness
= ((Randomness
<<3)-Randomness
)>>3)
269 int x
, y
, RandMod
= (Randomness
<<1)+1;
271 for (x
= HalfStep
; x
< Side
; x
+= Step
)
272 for (y
= HalfStep
; y
< Side
; y
+= Step
)
274 ((Map
[x
-HalfStep
][y
-HalfStep
]+
275 Map
[x
-HalfStep
][y
+HalfStep
]+
276 Map
[x
+HalfStep
][y
-HalfStep
]+
277 Map
[x
+HalfStep
][y
+HalfStep
])>>2)-Randomness
+RAND()%RandMod
;
279 for (x
= HalfStep
; x
< Side
; x
+= Step
) {
280 for (y
= 0; y
< Side
; y
+= Step
) {
281 int HeightSum
= Map
[x
-HalfStep
][y
]+Map
[x
+HalfStep
][y
];
284 HeightSum
+= Map
[x
][y
-HalfStep
];
288 HeightSum
+= Map
[x
][y
+HalfStep
];
291 if (Neighbours
== 4) HeightSum
>>= 2; else HeightSum
/= Neighbours
;
292 Map
[x
][y
] = HeightSum
-Randomness
+RAND()%RandMod
;
296 for (x
= 0; x
< Side
; x
+= Step
) {
297 for (y
= HalfStep
; y
< Side
; y
+= Step
) {
298 int HeightSum
= Map
[x
][y
-HalfStep
]+Map
[x
][y
+HalfStep
];
301 HeightSum
+= Map
[x
-HalfStep
][y
];
305 HeightSum
+= Map
[x
+HalfStep
][y
];
308 if (Neighbours
== 4) HeightSum
>>= 2; else HeightSum
/= Neighbours
;
309 Map
[x
][y
] = HeightSum
-Randomness
+RAND()%RandMod
;