Категория C1 • задача №1
Условие задачи
Дано:
окружность на плоскости задана координатами центра и радиусом. Даны две окружности. Требовалось определить, имеют ли они точку касания. Программист торопился и написал программу неправильно.
x1, y1, r1, x2, y2, r2 : real;
begin
clrscr;
writeln;
write('Введите координаты и радиус 1 - й окружности: ');
readln(x1, y1, r1);
write('Введите координаты и радиус 2 - й окружности: ');
readln(x2, y2, r2);
if (sqrt(sqr(x2 - x1) + sqr(y2 - y1)) = r1 + r2) or
(sqrt(sqr(x2 - x1) + sqr(y2 - y1)) = abs(r1 - r2)) then
write('Да')
else
write('Нет');
Найти:
последовательно выполните следующее:
приведите пример таких исходных данных, при которых программа работает неправильно;
укажите, как нужно доработать программу, чтобы не было случаев ее неправильной работы.
Решение
I этап: алгоритмическая часть.
Нужно детерминировать все случаи когда окружности имеют общую точку касания:
окружности имеют внешнюю точку касания, то есть, когда ни одна из окружностей не находится внутри другой;
окружности имеют внутреннюю точку касания, то есть, когда одна из окружностей принадлежит другой окружности.
Программа не учитывает случая, когда одна окружность находится внутри другой и имеет внутреннюю точку касания. Например, рассмотрим две окружности с центрами и радиусами:
x1 = 2, y1 = 2, r1 = 2;
x2 = 2, y2 = 3, r2 = 1.
В указанном варианте, необходимо производить вычитание значений радиусов, а не сложение (причем из большего радиуса нужно вычитать меньший радиус или использовать операцию взятия модуля).
Если окружности имеют внешнюю точку касания, то необходимо производить сложение значений радиусов и именно этот вариант был рассмотрен программистом. То есть, основная недоработка программиста данной программы является тот факт, что разработчик забыл рассмотреть ситуацию касания окружностей внутренней точкой.
II этап: доработка исходной программы, используя язык программирования Turbo Pascal 7.0.
uses
{подключаем модуль crt – console run time. Данный модуль содержит специализированные подпрограммы для обработки текста, звука, клавиатурных событий}
crt;
var
{х1, y1 – координата абсциссы и ординаты первой окружности r1 – радиус первой окружности х2, y2 – координата абсциссы и ординаты второй окружности r2 – радиус второй окружности}
x1, y1, r1, x2, y2, r2 : real;
begin
{очистка дисплея монитора от прошлых выводов}
clrscr;
{диалог о вводе характеристик первой окружности}
write('Введите координаты и радиус 1-й окружности: ');
{считывание координат и радиуса 1-й окружности с клавиатуры}
readln(x1, y1, r1);
{диалог о вводе характеристик второй окружности}
write('Введите координаты и радиус 2-й окружности: ');
{считывание координат и радиуса 2-й окружности с клавиатуры}
readln(x2, y2, r2);
{две окружности могут иметь общую точку касания в нескольких вариантах. Первый вариант: окружности имеют внешнюю точку касания. В данном случае, расстояние между их центрами должно быть ровно сумме их радиусов. Второй вариант: окружности имеют внутреннюю точку касания, то есть, когда одна из окружностей, полностью находится в области другой окружности. В этом случае, расстояние между их центрами должно быть равно модулю разности их радиусов.}
if (sqrt(sqr(x2 - x1) + sqr(y2 - y1)) = r1 + r2) or
(sqrt(sqr(x2 - x1) + sqr(y2 - y1)) = abs(r1 - r2)) then
write('Да')
else
write('Нет');
{имитация задержки программы. Программа будет закрыта после нажатия произвольной клавиши на клавиатуре}
readkey;
end.
Вывод: |
главное, что не учел программист изначально - случай, когда окружности имеют внутреннюю точку касания. |
Резюме
произвели алгоритмизацию поставленной задачи;
выяснили ситуации, когда программа не работала корректно;
произвели доработку программного кода на языке программирования Turbo Pascal 7.0
Комментарии