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