Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Паскаль, Turbo Pascal, PascalABC.NET
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 24.11.2017, 19:45   #1
dimon_snake
Форумчанин
 
Регистрация: 05.11.2015
Сообщений: 167
Печаль Длина отрезка в круге

Здравствуйте. Столкнулся с проблемой - никак не могу решить.
Задача такая: есть координаты двух точек (начало и конец отрезка), координаты центра круга и радиус круга.
Нужно найти, какое расстояние отрезок проходит в круге, и вывести с тремя знаками после запятой. Если он проходит мимо, вывести -1.
Программа:
Код:
var
fi,fo:text;
x1,x2,x0,y1,y2,y0,r,b,a,c,p,h,a1,b1,c1,d,x11,x22,y11,y22,ot,k,bk:real;
begin
assign(fi,'expert.in');
assign(fo,'expert.out');
reset(fi);
rewrite(fo);
read(fi,x1,y1,x2,y2,x0,y0,r);
b:=sqrt(sqr(x2-x1)+sqr(y2-y1));
a:=sqrt(sqr(x0-x1)+sqr(y0-y1));
c:=sqrt(sqr(x0-x2)+sqr(y0-y2));
if (sqr(a)+sqr(b)-sqr(c)>0)and(sqr(c)+sqr(b)-sqr(a)>0) then 
  begin
    p:=(a+b+c)/2;
    h:=((sqrt(p*(p-a)*(p-b)*(p-c)))/b)*2;
  end
  else 
    begin
      if a>c then h:=c 
      else h:=a;
     end;
  if (h>=r) then
        begin
          write(fo,-1);
          exit;
        end
        else 
          begin
             if (a<=r)and(c<=r) then 
              begin
                write(fo,b:0:3);
                exit;
              end
              else if (a>r)and(c>r) then 
                begin
                  k:=(y2-y1)/(x2-x1);
                  bk:=y1-k*x1;                
                  a1:=1+sqr(k);                
                  b1:=2*(k*bk-k*y0-x0);                
                  c1:=sqr(x0)+sqr(bk)+sqr(y0)-2*bk*y0-r*r;               
                  d:=sqr(b1)-4*a1*c1;
                  x11:=(-b1+sqrt(d))/(2*a1);               
                  x22:=(-b1-sqrt(d))/(2*a1);                
                  y11:=k*x11+bk;
                  y22:=k*x22+bk;
                  ot:=sqrt(sqr(x22-x11)+sqr(y22-y11));
                  write(fo,ot:0:3);
                 
                  exit;
                 end;
                end;
                close(fo);
 end.
Сначала я проверяю, проходит ли вообще отрезок в круге или нет. Нахожу самое короткое расстояние от центра к отрезку, если оно >=r то ответ - 0.
Самое короткое расстояние к отрезку - либо перпендикуляр, если его можно опустить, либо расстояние от центра к одной из точек отрезка.
Затем проверяю, лежат ли обе точки в круге. Если да, то ответ - весь отрезок.
Если же обе точки лежат за пределами круга, то нужно найти точку входа в круг и точку выхода.
Для этого я использовал уравнение прямой и уравнение круга, нашел эти точки и посчитал расстояние между ними.
Я только не пойму, что делать, когда одна точка внутри круга, а другая - снаружи. Тогда нужно найти единственную точку входа отрезка в круг (ведь выхода нет), но как это сделать?
И еще один вопрос.
При входных данных
2 1 13 4 7 6 5
ответ должен быть 7.125
Когда я включаю программу без файлов, то есть ввожу вручную, то ответ получается такой же.
А когда шлю на сайт с файлами, то мне пишет, что формат ввода неправильный. Что это может быть?
Заранее спасибо.
dimon_snake вне форума Ответить с цитированием
Старый 24.11.2017, 19:57   #2
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 19,042
По умолчанию

http://www.programmersforum.ru/showthread.php?t=301889

Год уже решаешь?
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 24.11.2017, 20:15   #3
dimon_snake
Форумчанин
 
Регистрация: 05.11.2015
Сообщений: 167
По умолчанию

да нет, дорешать решил
dimon_snake вне форума Ответить с цитированием
Старый 25.11.2017, 17:09   #4
СтудПом
Форумчанин
 
Регистрация: 08.11.2017
Сообщений: 347
По умолчанию

Думаю, будет лучше найти пересечение прямой с окружностью, если оно есть, то имеем отрезок этой прямой и задача сводится к определению пересечения отрезков (интервалов). Так как оба отрезка находятся на одной прямой, то достаточно проверить только вдоль одной из осей X или Y. Надо предусмотреть вариант, когда прямая параллельна одной из осей, т.е. интервал м.б. нулевым.
СтудПом вне форума Ответить с цитированием
Старый 25.11.2017, 20:57   #5
digitalis
Старожил
 
Аватар для digitalis
 
Регистрация: 04.02.2011
Сообщений: 4,537
По умолчанию

Несмотря на простоту, задачка интересная. Если завтра Ferrari победит, на радостях напишу. А так могу только алгоритм на словах описать.
- Если расстояние от центра до прямой > радиуса - решение 0 - не пересекаются.
- Если расстояние от обоих концов отрезка до центра < радиуса - сам отрезок и есть решение.
- Третий вариант - одна точка внутри круга, одна вне - находим пересечение окружности с отрезком, и эта точка + та точка, что внутри - и есть решение.
- Четвертый вариант - оба конца отрезка вне, но расстояние от центра до прямой < радиуса - находим обе точки пересечения.
Возможен вариант: расстояние от центра до прямой = радиусу, то это касание в одной точке, но этот вариант всерьез рассматривать не стоит, бо равенство 2 действительных чисел - понятие химерическое, можно говорить лишь о |разность 2-х чисел| < наперед заданного значения и есть приблизительное равенство.
dimon_snake
Цитата:
А когда шлю на сайт с файлами
Как можно просто послать на - это я представляю, а на сайт с файлами - это куда ?

Последний раз редактировалось digitalis; 25.11.2017 в 21:07.
digitalis вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Разработать метод f(x1, y1, x2, y2), который вычисляет длину отрезка по координатам вершин (x1, y1) и (x2, y2), и метод d(a, b, c), который вычисляет периметр треугольника по длина scarecrow_1 C# (си шарп) 3 14.10.2016 19:56
Решить задачу: Найдите кривую , проходящую через точку А(1;2) , для которой длина отрезка оси абсцисс , отсекаемого касательной... Фима Помощь студентам 2 14.12.2015 21:43
Равномерное распределение точек в круге Arigato Мультимедиа в Delphi 12 23.11.2014 23:11
как для построения отрезка по двум точкам на плоскости ХОУ и далее, из одного из концов построенного отрезка построить второй отре IZOPGRAM Общие вопросы Delphi 2 27.12.2012 09:28
Задача о круге на плоскости. pdef Помощь студентам 3 22.09.2011 00:47