59 lines
1.3 KiB
C++
59 lines
1.3 KiB
C++
#include "iterators.hpp"
|
|
|
|
using namespace world::iterator;
|
|
|
|
std::unique_ptr<Abstract> world::iterator::Get(world::action::Shape shape, uint16_t radius) {
|
|
switch (shape) {
|
|
case world::action::Shape::Cube:
|
|
return std::make_unique<Cube>(radius);
|
|
case world::action::Shape::RawSphere:
|
|
return std::make_unique<RawSphere>(radius);
|
|
default:
|
|
return std::unique_ptr<Abstract>(nullptr);
|
|
}
|
|
}
|
|
|
|
bool Cube::next(pair& out) {
|
|
if (pos.z > radius)
|
|
return false;
|
|
|
|
out.first = pos;
|
|
out.second = 1;
|
|
|
|
// MAYBE: use linear idx to make branch less
|
|
if (pos.x < radius) {
|
|
pos.x++;
|
|
} else {
|
|
pos.x = -radius;
|
|
if (pos.y < radius) {
|
|
pos.y++;
|
|
} else {
|
|
pos.y = -radius;
|
|
pos.z++;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool RawSphere::next(pair& out) {
|
|
if (pos.x > radius)
|
|
return false;
|
|
|
|
out.first = pos;
|
|
out.second = 1;
|
|
|
|
if (pos.z < dz) {
|
|
pos.z++;
|
|
} else {
|
|
if (pos.y < dy) {
|
|
pos.y++;
|
|
} else {
|
|
pos.x++;
|
|
dy = floor(sqrt(radius * radius - pos.x * pos.x));
|
|
pos.y = -dy;
|
|
}
|
|
dz = floor(sqrt(dy * dy - pos.y * pos.y));
|
|
pos.z = -dz;
|
|
}
|
|
return true;
|
|
} |