ブレゼンハムのアルゴリズムもgeneratorで実装すると楽だ
Bresenham's Line Algorithm
ペイントソフトの直線ツールみたいな、ドットの直線をかくようなアルゴリズムがある
こういうのもgeneratorだと書きやすいな

実装例
#include <Siv3D.hpp> #include <experimental/generator> template<class T> using generator = std::experimental::generator<T>; // ブレゼンハムのアルゴリズム generator<Point> BresenhamLine(Point start, Point end) { int32 dx = Abs(end.x - start.x); int32 dy = Abs(end.y - start.y); int32 sx = (start.x < end.x) ? 1 : -1; int32 sy = (start.y < end.y) ? 1 : -1; int32 error = dx - dy; while (true) { co_yield start; if (start == end) { co_return; } int e2 = 2 * error; if (e2 > -dy) { error = error - dy; start.x += sx; } if (e2 < dx) { error = error + dx; start.y += sy; } } } void Main() { Window::Resize(600, 600); Scene::SetBackground(Palette::White); Grid<bool> grid(60, 60); Optional<Point> start; Optional<Point> end; while (System::Update()) { Point mousePos = Cursor::Pos() / 10; mousePos.x = Clamp(mousePos.x, 0, 59); mousePos.y = Clamp(mousePos.y, 0, 59); if (MouseL.down()) { if (!start) { start = mousePos; } else if (!end) { end = mousePos; for (auto [x, y] : BresenhamLine(*start, mousePos)) { grid[y][x] = true; } } else { start = mousePos; end = s3d::none; } } else if (MouseR.down()) { grid.clear(); grid.resize(60, 60); } for (size_t i = 1; i < 60; ++i) { Line({ i * 10, 0 }, { i * 10,600 }).draw(Palette::Gray); Line({ 0, i*10 }, { 600, i * 10 }).draw(Palette::Gray); } for (size_t y = 0; y < grid.height(); ++y) { for (size_t x = 0; x < grid.width(); ++x) { if (grid[y][x]) { Rect(x * 10, y * 10, 10, 10).draw(Palette::Black); } } } if (!start) { Rect(mousePos * 10, 10, 10).draw(Palette::Red.withAlpha(128)); } else if (!end) { for (auto [x, y] : BresenhamLine(*start, mousePos)) { Rect(x * 10, y * 10, 10, 10).draw(Palette::Red.withAlpha(128)); } } } }