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
00099 void TileArea::ClampToMap()
00100 {
00101 assert(this->tile < MapSize());
00102 this->w = min(this->w, MapSizeX() - TileX(this->tile));
00103 this->h = min(this->h, MapSizeY() - TileY(this->tile));
00104 }
00105
00111 DiagonalTileIterator::DiagonalTileIterator(TileIndex corner1, TileIndex corner2) : TileIterator(corner2), base_x(TileX(corner2)), base_y(TileY(corner2)), a_cur(0), b_cur(0)
00112 {
00113 assert(corner1 < MapSize());
00114 assert(corner2 < MapSize());
00115
00116 int dist_x = TileX(corner1) - TileX(corner2);
00117 int dist_y = TileY(corner1) - TileY(corner2);
00118 this->a_max = dist_x + dist_y;
00119 this->b_max = dist_y - dist_x;
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129 if (this->a_max > 0) {
00130 this->a_max++;
00131 } else {
00132 this->a_max--;
00133 }
00134
00135 if (this->b_max > 0) {
00136 this->b_max++;
00137 } else {
00138 this->b_max--;
00139 }
00140 }
00141
00145 TileIterator &DiagonalTileIterator::operator++()
00146 {
00147 assert(this->tile != INVALID_TILE);
00148
00149
00150 bool new_line = false;
00151 do {
00152
00153 if (this->a_max == 1 || this->a_max == -1) {
00154
00155 this->a_cur = 0;
00156 if (this->b_max > 0) {
00157 this->b_cur = min(this->b_cur + 2, this->b_max);
00158 } else {
00159 this->b_cur = max(this->b_cur - 2, this->b_max);
00160 }
00161 } else {
00162
00163 if (this->a_max > 0) {
00164 this->a_cur += 2;
00165 new_line = this->a_cur >= this->a_max;
00166 } else {
00167 this->a_cur -= 2;
00168 new_line = this->a_cur <= this->a_max;
00169 }
00170 if (new_line) {
00171
00172
00173
00174 this->a_cur = abs(this->a_cur) % 2 ? 0 : (this->a_max > 0 ? 1 : -1);
00175
00176 if (this->b_max > 0) {
00177 ++this->b_cur;
00178 } else {
00179 --this->b_cur;
00180 }
00181 }
00182 }
00183
00184
00185 uint x = this->base_x + (this->a_cur - this->b_cur) / 2;
00186 uint y = this->base_y + (this->b_cur + this->a_cur) / 2;
00187
00188 this->tile = x >= MapSizeX() || y >= MapSizeY() ? INVALID_TILE : TileXY(x, y);
00189 } while (this->tile > MapSize() && this->b_max != this->b_cur);
00190
00191 if (this->b_max == this->b_cur) this->tile = INVALID_TILE;
00192 return *this;
00193 }