forked from aburch/simutrans
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathkoord.h
148 lines (115 loc) · 3.07 KB
/
koord.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#ifndef KOORD_H
#define KOORD_H
#include <stdlib.h>
#include "ribi.h"
#include "../simtypes.h"
class loadsave_t;
/**
* 2d Koordinaten
*/
class koord
{
public:
// this is set by einstelugen_t
static uint32 locality_factor;
sint16 x;
sint16 y;
koord() : x(0), y(0) {}
koord(short xp, short yp) : x(xp), y(yp) {}
koord(loadsave_t* file);
koord(ribi_t::ribi ribi) { *this = from_ribi[ribi]; }
koord(hang_t::typ hang) { *this = from_hang[hang]; }
// use this instead of koord(simrand(x),simrand(y)) to avoid
// different order on different compilers
static koord koord_random(uint16 xrange, uint16 yrange);
void rdwr(loadsave_t *file);
const char *get_str() const;
const char *get_fullstr() const; // including brackets
const koord& operator += (const koord & k)
{
x += k.x;
y += k.y;
return *this;
}
const koord& operator -= (const koord & k)
{
x -= k.x;
y -= k.y;
return *this;
}
void rotate90( sint16 y_size )
{
if( (x&y)<0 ) {
// do not rotate illegal coordinates
return;
}
sint16 new_x = y_size-y;
y = x;
x = new_x;
}
static const koord invalid;
static const koord nord;
static const koord sued;
static const koord ost;
static const koord west;
// die 4 Grundrichtungen als Array
static const koord nsow[4];
// 8 next neighbours
static const koord neighbours[8];
private:
static const koord from_ribi[16];
static const koord from_hang[16];
};
static inline uint32 koord_distance(const koord &a, const koord &b)
{
return abs(a.x - b.x) + abs(a.y - b.y);
}
// Knightly : shortest distance in cardinal (N, E, S, W) and ordinal (NE, SE, SW, NW) directions
static inline uint32 shortest_distance(const koord &a, const koord &b)
{
const uint32 x_offset = abs(a.x - b.x);
const uint32 y_offset = abs(a.y - b.y);
// square root of 2 is estimated by 181/128; 64 is for rounding
if( x_offset>=y_offset ) {
return (x_offset - y_offset) + ( ((y_offset * 181u) + 64u) >> 7 );
}
else {
return (y_offset - x_offset) + ( ((x_offset * 181u) + 64u) >> 7 );
}
}
// Knightly : multiply the value by the distance weight
static inline uint32 weight_by_distance(const sint32 value, const uint32 distance)
{
return value<=0 ? 0 : 1+(uint32)( ( ((sint64)value<<8) * koord::locality_factor ) / (sint64)( koord::locality_factor + (distance < 4u ? 4u : distance) ) );
}
static inline koord operator * (const koord &k, const sint16 m)
{
return koord(k.x * m, k.y * m);
}
static inline koord operator / (const koord &k, const sint16 m)
{
return koord(k.x / m, k.y / m);
}
static inline bool operator == (const koord &a, const koord &b)
{
// only this works with O3 optimisation!
return ((a.x-b.x)|(a.y-b.y))==0;
}
static inline bool operator != (const koord &a, const koord &b)
{
// only this works with O3 optimisation!
return ((a.x-b.x)|(a.y-b.y))!=0;
}
static inline koord operator + (const koord &a, const koord &b)
{
return koord(a.x + b.x, a.y + b.y);
}
static inline koord operator - (const koord &a, const koord &b)
{
return koord(a.x - b.x, a.y - b.y);
}
static inline koord operator - (const koord &a)
{
return koord(-a.x, -a.y);
}
#endif