// Copyright 2026, University of Freiburg
// Chair of Algorithms and Data Structures
// Author: Hannah Bast <bast@cs.uni-freiburg.de>
#include "./NCursesTerminalManager.h"
#include "./TerminalManager.h"
#include <algorithm>
#include <cmath>
#include <iostream>
#include <unistd.h>
#include <vector>
// A class holding a polygon, that is, a sequence of points in the plane.
class Polygon {
public:
// An empty polygon.
Polygon() = default;
// A polygon approximating a donut. That is, the corner points are arranged
// equidistantly on two concentric circles around the given center point,
// with the given inner and outer radius.
Polygon(int centerRow, int centerCol, int numPoints, int innerRadius,
int outerRadius) {
std::vector<int> radii = {innerRadius, outerRadius};
for (int radius : radii) {
points_.emplace_back();
auto &ring = points_.back();
for (int i = 0; i < numPoints; ++i) {
double angle = 2 * M_PI * i / numPoints;
int row = centerRow + static_cast<int>(radius * std::sin(angle));
int col = centerCol + static_cast<int>(radius * std::cos(angle));
ring.emplace_back(row, col);
}
}
}
// Get the points of the polygon.
const std::vector<std::vector<std::pair<int, int>>> &points() const {
return points_;
}
private:
// The points of the "rings" of the polygon, in order for each ring.
std::vector<std::vector<std::pair<int, int>>> points_;
};
int main() {
// Get terminal manager and screen dimensions.
TerminalManager *terminalManager = new NCursesTerminalManager();
int numRows = terminalManager->numRows();
int numCols = terminalManager->numCols();
// Create a polygon using the class above.
int centerRow = numRows / 2;
int centerCol = numCols / 2;
int innerRadius = std::min(numRows, numCols) / 5 - 1;
int outerRadius = std::min(numRows, numCols) / 2 - 1;
Polygon polygon(centerRow, centerCol, 5, innerRadius, outerRadius);
// Draw the corners of the polygon.
for (auto &ring : polygon.points()) {
for (size_t i = 0; i < ring.size(); ++i) {
const auto &[row, col] = ring[i];
terminalManager->drawPixel(row, col, TerminalManager::Green);
}
}
// Wait for the user to press any key to exit.
while (true) {
UserInput userInput = terminalManager->getUserInput();
if (userInput.keycode_ != -1) {
break;
}
usleep(10'000);
}
// Clean up and exit.
delete terminalManager;
return 0;
}