tilearea.cpp
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 TileArea::TileArea(TileIndex start, TileIndex end)
00022 {
00023 uint sx = TileX(start);
00024 uint sy = TileY(start);
00025 uint ex = TileX(end);
00026 uint ey = TileY(end);
00027
00028 if (sx > ex) Swap(sx, ex);
00029 if (sy > ey) Swap(sy, ey);
00030
00031 this->tile = TileXY(sx, sy);
00032 this->w = ex - sx + 1;
00033 this->h = ey - sy + 1;
00034 }
00035
00040 void TileArea::Add(TileIndex to_add)
00041 {
00042 if (this->tile == INVALID_TILE) {
00043 this->tile = to_add;
00044 this->w = 1;
00045 this->h = 1;
00046 return;
00047 }
00048
00049 uint sx = TileX(this->tile);
00050 uint sy = TileY(this->tile);
00051 uint ex = sx + this->w - 1;
00052 uint ey = sy + this->h - 1;
00053
00054 uint ax = TileX(to_add);
00055 uint ay = TileY(to_add);
00056
00057 sx = min(ax, sx);
00058 sy = min(ay, sy);
00059 ex = max(ax, ex);
00060 ey = max(ay, ey);
00061
00062 this->tile = TileXY(sx, sy);
00063 this->w = ex - sx + 1;
00064 this->h = ey - sy + 1;
00065 }
00066
00072 bool TileArea::Intersects(const TileArea &ta) const
00073 {
00074 if (ta.w == 0 || this->w == 0) return false;
00075
00076 assert(ta.w != 0 && ta.h != 0 && this->w != 0 && this->h != 0);
00077
00078 uint left1 = TileX(this->tile);
00079 uint top1 = TileY(this->tile);
00080 uint right1 = left1 + this->w - 1;
00081 uint bottom1 = top1 + this->h - 1;
00082
00083 uint left2 = TileX(ta.tile);
00084 uint top2 = TileY(ta.tile);
00085 uint right2 = left2 + ta.w - 1;
00086 uint bottom2 = top2 + ta.h - 1;
00087
00088 return !(
00089 left2 > right1 ||
00090 right2 < left1 ||
00091 top2 > bottom1 ||
00092 bottom2 < top1
00093 );
00094 }
00095
00101 bool TileArea::Contains(TileIndex tile) const
00102 {
00103 if (this->w == 0) return false;
00104
00105 assert(this->w != 0 && this->h != 0);
00106
00107 uint left = TileX(this->tile);
00108 uint top = TileY(this->tile);
00109 uint tile_x = TileX(tile);
00110 uint tile_y = TileY(tile);
00111
00112 return tile_x >= left && tile_x < left + this->w && tile_y >= top && tile_y < top + this->h;
00113 }
00114
00118 void TileArea::ClampToMap()
00119 {
00120 assert(this->tile < MapSize());
00121 this->w = min(this->w, MapSizeX() - TileX(this->tile));
00122 this->h = min(this->h, MapSizeY() - TileY(this->tile));
00123 }
00124
00130 DiagonalTileIterator::DiagonalTileIterator(TileIndex corner1, TileIndex corner2) : TileIterator(corner2), base_x(TileX(corner2)), base_y(TileY(corner2)), a_cur(0), b_cur(0)
00131 {
00132 assert(corner1 < MapSize());
00133 assert(corner2 < MapSize());
00134
00135 int dist_x = TileX(corner1) - TileX(corner2);
00136 int dist_y = TileY(corner1) - TileY(corner2);
00137 this->a_max = dist_x + dist_y;
00138 this->b_max = dist_y - dist_x;
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148 if (this->a_max > 0) {
00149 this->a_max++;
00150 } else {
00151 this->a_max--;
00152 }
00153
00154 if (this->b_max > 0) {
00155 this->b_max++;
00156 } else {
00157 this->b_max--;
00158 }
00159 }
00160
00164 TileIterator &DiagonalTileIterator::operator++()
00165 {
00166 assert(this->tile != INVALID_TILE);
00167
00168
00169 bool new_line = false;
00170 do {
00171
00172 if (this->a_max == 1 || this->a_max == -1) {
00173
00174 this->a_cur = 0;
00175 if (this->b_max > 0) {
00176 this->b_cur = min(this->b_cur + 2, this->b_max);
00177 } else {
00178 this->b_cur = max(this->b_cur - 2, this->b_max);
00179 }
00180 } else {
00181
00182 if (this->a_max > 0) {
00183 this->a_cur += 2;
00184 new_line = this->a_cur >= this->a_max;
00185 } else {
00186 this->a_cur -= 2;
00187 new_line = this->a_cur <= this->a_max;
00188 }
00189 if (new_line) {
00190
00191
00192
00193 this->a_cur = abs(this->a_cur) % 2 ? 0 : (this->a_max > 0 ? 1 : -1);
00194
00195 if (this->b_max > 0) {
00196 ++this->b_cur;
00197 } else {
00198 --this->b_cur;
00199 }
00200 }
00201 }
00202
00203
00204 uint x = this->base_x + (this->a_cur - this->b_cur) / 2;
00205 uint y = this->base_y + (this->b_cur + this->a_cur) / 2;
00206
00207 this->tile = x >= MapSizeX() || y >= MapSizeY() ? INVALID_TILE : TileXY(x, y);
00208 } while (this->tile > MapSize() && this->b_max != this->b_cur);
00209
00210 if (this->b_max == this->b_cur) this->tile = INVALID_TILE;
00211 return *this;
00212 }