Попадание точки в заштрихованную область - C (СИ) (152086)
Формулировка задачи:
Написать программу, которая определяет, попадает ли точка с заданными координатами в область, закрашенную на рисунке серым цветом. Результат работы программы вывести в виде текстового сообщения. Параметр R вводится с клавиатуры.
Решение задачи: «Попадание точки в заштрихованную область»
textual
Листинг программы
#include <math.h> // hypot, atan2
#include <stdio.h> // puts, scanf
typedef struct point {
double x;
double y;
} Point;
void
Point_Init(Point* const this, const double x, const double y)
{
this->x = x;
this->y = y;
}
double
Point_Distance(const Point* const this, const Point* const p)
{
return hypot(this->x - p->x, this->y - p->y);
}
double
Point_Angle(const Point* const this)
{
if( this->x == 0.0 ) {
return this->y < 0.0? -90.0 : 90.0;
}
return atan2(this->y, this->x) * 180.0 * M_1_PI;
}
typedef struct circle {
Point center;
double radius;
} Circle;
void
Circle_Init(Circle* const this, const Point* const center, const double radius)
{
this->center = *center;
this->radius = radius;
}
int
Circle_Contains(const Circle* const this, const Point* const p)
{
return Point_Distance(&(this->center), p) <= this->radius;
}
typedef struct figure {
Circle circle;
double angle;
} Figure;
void
Figure_Init(Figure* const this, const double radius, const double angle)
{
Point p;
Point_Init(&p, 0.0, 0.0);
Circle_Init(&(this->circle), &p, radius);
this->angle = angle;
}
int
Figure_Contains(const Figure* const this, const Point* const p)
{
if( !Circle_Contains(&(this->circle), p) ) { return 0; }
double a = Point_Angle(p);
return (a <= 90.0 && a >= this->angle)
|| (a <= -90.0 && a >= this->angle - 180.0);
}
int
main(void)
{
const double angle = 45.0;
while ( 1 ) {
double x, y, radius;
do {
puts("Input x, y, radius:");
} while( scanf("%lf %lf %lf", &x, &y, &radius) != 3 );
if( radius <= 0.0 ) { break; }
Figure figure;
Figure_Init(&figure, radius, angle);
Point point;
Point_Init(&point, x, y);
puts( Figure_Contains(&figure, &point)? "In" : "Out" );
}
return 0;
}
Объяснение кода листинга программы
- Включаем необходимые заголовочные файлы для использования функций hypot и atan2 из math.h, а также для использования функций puts и scanf из stdio.h.
- Объявляем структуру point, которая представляет точку в двумерном пространстве, и определяем функцию Point_Init для инициализации переменных структуры.
- Определяем функцию Point_Distance для вычисления расстояния между двумя точками в двумерном пространстве.
- Определяем функцию Point_Angle для вычисления угла, который образует точка относительно положительной оси x.
- Объявляем структуру circle, которая представляет окружность в двумерном пространстве, и определяем функцию Circle_Init для инициализации переменных структуры.
- Определяем функцию Circle_Contains для проверки, содержится ли точка внутри окружности.
- Объявляем структуру figure, которая представляет фигуру на плоскости, состоящую из окружности и угла, и определяем функцию Figure_Init для инициализации переменных структуры.
- Определяем функцию Figure_Contains для проверки, содержится ли точка внутри фигуры.
- В функции main считываем три числа (x, y, radius) с помощью scanf и проверяем, что они успешно считались.
- Если радиус меньше или равен нулю, то выходим из цикла.
- Создаем экземпляр фигуры с помощью функции Figure_Init.
- Создаем экземпляр точки с помощью функции Point_Init.
- Выводим сообщение
In, если точка содержится в фигуре, иOut, если точка не содержится в фигуре. - Повторяем шаги 9-13 до тех пор, пока пользователь не введет радиус, равный нулю.
- Возвращаем 0, чтобы указать, что программа успешно завершилась.