#include <iostream> #include <iomanip> #include <fstream> #include <list> #include <algorithm> #include <stdlib.h> #include <time.h> bool ps_rcintersect(const double* R, const double *C) { double r = C[2]; double r2 = r * r; // Translate coordinates, placing the circle center at the origin double x1 = R[0] - C[0], x2 = R[2] - C[0]; double y1 = R[1] - C[1], y2 = R[3] - C[1]; if (x2 < 0.0) // R to left of circle center { if (y2 < 0.0) // R in left corner { return (x2 * x2 + y2 * y2 < r2); } else if (y1 > 0.0) // R in upper left corner { return (x2 * x2 + y1 * y1 < r2); } else // R due West of circle { return (-x2 < r); } } else if (x1 > 0.0) // R to right of circle center { if (y2 < 0.0) // R in lower right corner { return (x1 * x1 + y2 * y2 < r2); } else if (y1 > 0.0) // R in upper right corner { return (x1 * x1 + y1 * y1 < r2); } else // R due East of circle { return (x1 < r); } } else { if (y2 < 0.0) // R due South of circle { return (-y2 < r); } else if (y1 > 0.0) // R due North of circle { return (y1 < r); } else // R contains circle centerpoint { return true; } } } struct circle { double x; double y; double r; }; std::istream& operator>> (std::istream& in, circle& s) { return in >> s.x >> s.y >> s.r; } std::ostream& operator<< (std::ostream& out, const circle& s) { return out << s.x << ' ' << s.y << ' ' << s.r; } class circle_predicate { double rect[4]; public: circle_predicate(double x1, double y1, double x2, double y2) { rect[0] = x1; rect[1] = y1; rect[2] = x2; rect[3] = y2; } bool operator() (const circle& s) { double g[3]; g[0] = s.x; g[1] = s.y; g[2] = s.r; return ps_rcintersect(rect, g); } }; bool operator < (const circle& lhs, const circle& rhs) { return (lhs.r < rhs.r); } int driver(int argc, char** argv) { // получаем координаты прямоугольника double x1 = atof(argv[1]); double y1 = atof(argv[2]); double x2 = atof(argv[3]); double y2 = atof(argv[4]); // загружаем набор окружностей typedef std::list<circle> circle_list; circle_list g; std::ifstream in(argv[5]); std::copy(std::istream_iterator<circle>(in), std::istream_iterator<circle>(), std::back_inserter(g)); // удаляем окружности, имеющие общие точки с прямоугольником g.remove_if(circle_predicate(x1, y1, x2, y2)); // сортируем окружности по возрастанию радиуса g.sort(); // печатаем список окружностей std::ofstream f(__FILE__ ".output"); std::copy(g.begin(), g.end(), std::ostream_iterator<circle>(f, "\n")); return 0; } double drand() { return ((double) rand() / RAND_MAX); } int main() { char* filename = __FILE__ ".input"; char* argv[] = { "", "2.0", "1.0", "5.0", "3.0", filename }; // инициализируем датчик случайных чисел srand(time(0)); { // записываем 10 окружностей в файл std::ofstream f(filename); for (int i = 0; i < 10; ++i) { circle s; s.x = 10.0 * drand(); s.y = 10.0 * drand(); s.r = 10.0 * drand(); f << s << std::endl; } } // смотрим, что получается return driver(6, argv); } |