Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00012 #include "stdafx.h"
00013
00014 #include "tilearea_type.h"
00015
00021 OrthogonalTileArea::OrthogonalTileArea(TileIndex start, TileIndex end)
00022 {
00023 assert(start < MapSize());
00024 assert(end < MapSize());
00025
00026 uint sx = TileX(start);
00027 uint sy = TileY(start);
00028 uint ex = TileX(end);
00029 uint ey = TileY(end);
00030
00031 if (sx > ex) Swap(sx, ex);
00032 if (sy > ey) Swap(sy, ey);
00033
00034 this->tile = TileXY(sx, sy);
00035 this->w = ex - sx + 1;
00036 this->h = ey - sy + 1;
00037 }
00038
00043 void OrthogonalTileArea::Add(TileIndex to_add)
00044 {
00045 if (this->tile == INVALID_TILE) {
00046 this->tile = to_add;
00047 this->w = 1;
00048 this->h = 1;
00049 return;
00050 }
00051
00052 uint sx = TileX(this->tile);
00053 uint sy = TileY(this->tile);
00054 uint ex = sx + this->w - 1;
00055 uint ey = sy + this->h - 1;
00056
00057 uint ax = TileX(to_add);
00058 uint ay = TileY(to_add);
00059
00060 sx = min(ax, sx);
00061 sy = min(ay, sy);
00062 ex = max(ax, ex);
00063 ey = max(ay, ey);
00064
00065 this->tile = TileXY(sx, sy);
00066 this->w = ex - sx + 1;
00067 this->h = ey - sy + 1;
00068 }
00069
00075 bool OrthogonalTileArea::Intersects(const OrthogonalTileArea &ta) const
00076 {
00077 if (ta.w == 0 || this->w == 0) return false;
00078
00079 assert(ta.w != 0 && ta.h != 0 && this->w != 0 && this->h != 0);
00080
00081 uint left1 = TileX(this->tile);
00082 uint top1 = TileY(this->tile);
00083 uint right1 = left1 + this->w - 1;
00084 uint bottom1 = top1 + this->h - 1;
00085
00086 uint left2 = TileX(ta.tile);
00087 uint top2 = TileY(ta.tile);
00088 uint right2 = left2 + ta.w - 1;
00089 uint bottom2 = top2 + ta.h - 1;
00090
00091 return !(
00092 left2 > right1 ||
00093 right2 < left1 ||
00094 top2 > bottom1 ||
00095 bottom2 < top1
00096 );
00097 }
00098
00104 bool OrthogonalTileArea::Contains(TileIndex tile) const
00105 {
00106 if (this->w == 0) return false;
00107
00108 assert(this->w != 0 && this->h != 0);
00109
00110 uint left = TileX(this->tile);
00111 uint top = TileY(this->tile);
00112 uint tile_x = TileX(tile);
00113 uint tile_y = TileY(tile);
00114
00115 return IsInsideBS(tile_x, left, this->w) && IsInsideBS(tile_y, top, this->h);
00116 }
00117
00121 void OrthogonalTileArea::ClampToMap()
00122 {
00123 assert(this->tile < MapSize());
00124 this->w = min(this->w, MapSizeX() - TileX(this->tile));
00125 this->h = min(this->h, MapSizeY() - TileY(this->tile));
00126 }
00127
00133 DiagonalTileArea::DiagonalTileArea(TileIndex start, TileIndex end) : tile(start)
00134 {
00135 assert(start < MapSize());
00136 assert(end < MapSize());
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146 this->a = TileY(end) + TileX(end) - TileY(start) - TileX(start);
00147 this->b = TileY(end) - TileX(end) - TileY(start) + TileX(start);
00148 if (this->a > 0) {
00149 this->a++;
00150 } else {
00151 this->a--;
00152 }
00153
00154 if (this->b > 0) {
00155 this->b++;
00156 } else {
00157 this->b--;
00158 }
00159 }
00160
00166 bool DiagonalTileArea::Contains(TileIndex tile) const
00167 {
00168 int a = TileY(tile) + TileX(tile);
00169 int b = TileY(tile) - TileX(tile);
00170
00171 int start_a = TileY(this->tile) + TileX(this->tile);
00172 int start_b = TileY(this->tile) - TileX(this->tile);
00173
00174 int end_a = start_a + this->a;
00175 int end_b = start_b + this->b;
00176
00177
00178 if (start_a > end_a) {
00179 int tmp = start_a;
00180 start_a = end_a + 1;
00181 end_a = tmp + 1;
00182 }
00183 if (start_b > end_b) {
00184 int tmp = start_b;
00185 start_b = end_b + 1;
00186 end_b = tmp + 1;
00187 }
00188
00189 return (a >= start_a && a < end_a && b >= start_b && b < end_b);
00190 }
00191
00195 TileIterator &DiagonalTileIterator::operator++()
00196 {
00197 assert(this->tile != INVALID_TILE);
00198
00199
00200 bool new_line = false;
00201 do {
00202
00203 if (this->a_max == 1 || this->a_max == -1) {
00204
00205 this->a_cur = 0;
00206 if (this->b_max > 0) {
00207 this->b_cur = min(this->b_cur + 2, this->b_max);
00208 } else {
00209 this->b_cur = max(this->b_cur - 2, this->b_max);
00210 }
00211 } else {
00212
00213 if (this->a_max > 0) {
00214 this->a_cur += 2;
00215 new_line = this->a_cur >= this->a_max;
00216 } else {
00217 this->a_cur -= 2;
00218 new_line = this->a_cur <= this->a_max;
00219 }
00220 if (new_line) {
00221
00222
00223
00224 this->a_cur = abs(this->a_cur) % 2 ? 0 : (this->a_max > 0 ? 1 : -1);
00225
00226 if (this->b_max > 0) {
00227 ++this->b_cur;
00228 } else {
00229 --this->b_cur;
00230 }
00231 }
00232 }
00233
00234
00235 uint x = this->base_x + (this->a_cur - this->b_cur) / 2;
00236 uint y = this->base_y + (this->b_cur + this->a_cur) / 2;
00237
00238 this->tile = x >= MapSizeX() || y >= MapSizeY() ? INVALID_TILE : TileXY(x, y);
00239 } while (this->tile > MapSize() && this->b_max != this->b_cur);
00240
00241 if (this->b_max == this->b_cur) this->tile = INVALID_TILE;
00242 return *this;
00243 }