Модераторы: bsa
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Рисование примитивов, найти пересечение 
V
    Опции темы
leporel
Дата 1.7.2010, 20:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 109
Регистрация: 12.2.2008

Репутация: нет
Всего: -1



Как можно при рисовании на канве окружности и линии по заданным координатам определить координату(ы) пересечения этой окружности с прямой?

Это сообщение отредактировал(а) leporel - 1.7.2010, 20:18
PM MAIL   Вверх
RobinHoodPHD
Дата 1.7.2010, 21:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 78
Регистрация: 12.8.2007
Где: Русь

Репутация: нет
Всего: 2



Чисто математически задача решается так: (взято с исходник программы и подправлено, чтобы компилилось в студии)
Код

#include<stdio.h>
#include<iostream>
#include<math.h>
using namespace std;

void prover(float x,float y,float k,float b,float r)
{ //находим дискременант квадратного уравнения
      float d=(pow((2*k*b-2*x-2*y*k),2)-(4+4*k*k)*(b*b-r*r+x*x+y*y-2*y*b));
 
  //если он равен 0, уравнение не имеет решения
     if(d<0) {cout<<"\n\nПрямая и окружность не пересекаются";return;}
  
  //иначе находим корни квадратного уравнения
     float x1=((-(2*k*b-2*x-2*y*k)-sqrt(d))/(2+2*k*k));
     float x2=((-(2*k*b-2*x-2*y*k)+sqrt(d))/(2+2*k*k));
 //если абсциссы точек совпадают, то пересечение только в одной точке    
     if (x1==x2)  {printf("\n\nПрямая и окружность имеют точку касания:(%.2f,%.2f)",x1,y1); 
     return;}
 //иначе находим ординаты точек пересечения 
     float y1=k*x1+b;
     float y2=k*x2+b;
     printf("\n\nПрямая и окружность пересекаются в точках: (%.2f,%.2f),(%.2f,%.2f)",x1,y1,x2,y2); 
     return;
}
 
void main()
{ float x,y,x1,x2,y1,y2,k,b,r;
  cout<<"\nВведите координаты центра окружности:\n"<<"x=";
  cin>>x;
  cout<<"y=";
  cin>>y;
  cout<<"Введите радиус окружности:\n"<<"R=";
  cin>>r;
 
  cout<<"\nВведите координаты точек прямой:\n"<<"x1=";
  cin>>x1;
  cout<<"y1=";
  cin>>y1;
  cout<<"x2=";
  cin>>x2;
  cout<<"y2=";
  cin>>y2;
  k=(y1-y2)/(x1-x2);
  b=y1-k*x1;
  prover(x,y,k,b,r);
}

Собственно можно выдернуть отсюда функцию prover. Вроде работает верно, хотя проверял не дотошно.

PM MAIL   Вверх
leporel
Дата 1.7.2010, 23:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 109
Регистрация: 12.2.2008

Репутация: нет
Всего: -1



Спасибо 
PM MAIL   Вверх
leporel
Дата 1.7.2010, 23:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 109
Регистрация: 12.2.2008

Репутация: нет
Всего: -1



Я не правильно сказал, не линия, а задан отрезок, нужно хотяб определить пересекается или нет, а координаты можно по первому способу найти.

Или можно найти точки пересечения и проверить на принадлежность их к заданному отрезку?

Это сообщение отредактировал(а) leporel - 1.7.2010, 23:45
PM MAIL   Вверх
RobinHoodPHD
Дата 2.7.2010, 09:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 78
Регистрация: 12.8.2007
Где: Русь

Репутация: нет
Всего: 2



Можно проверить на принадлежность отрезку. 
Если у тебя Xп > max (X1,X2) или Xп < min(X1,X2) или Yп > max (Y1,Y2) или Yп < min(Y1,Y2)
где Xп,Yп - точка пересечения, X1,Y1,X2,Y2 - координаты концов отрезка
PM MAIL   Вверх
leporel
Дата 3.7.2010, 04:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 109
Регистрация: 12.2.2008

Репутация: нет
Всего: -1



А получше алгоритма нету? А это этот как то криво очень работает.

нашел здесь решение http://www.nbuv.gov.ua/portal/natural/Npdn...10/08yavmok.pdf
но только не знаю как продлить отрезок и найти точки пересечения с координатными осями и С

Это сообщение отредактировал(а) leporel - 3.7.2010, 04:39
PM MAIL   Вверх
leporel
Дата 3.7.2010, 05:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 109
Регистрация: 12.2.2008

Репутация: нет
Всего: -1



Вот что то получилось
Код

    int peres,iLabX=LabX->Text.ToInt(),iLabY2=LabY2->Text.ToInt(),iLabY1=LabY1->Text.ToInt(),
        iLabY=LabY->Text.ToInt(),iLabX1=LabX1->Text.ToInt(),iLabX2=LabX2->Text.ToInt(),iLabR=LabR->Text.ToInt();
    float x1,x2,y1,y2,d,A,B,C;
    
    A=iLabY2-iLabY1;
    B=iLabX1-iLabX2;
    C=iLabX2*iLabY1-iLabX1*iLabY2;


    d = pow(A*A*iLabY-B*(C+A*iLabX),2)-(A*A+B*B)*(pow(C+A*iLabX,2)+A*A*B*B-A*A*iLabR*iLabR);

    if(d<0)
    {
     peres=0;
     ShowMessage("Нет точек пресечения");
    }
     else
     {
         y1=pow(A,2)*iLabY-B*(C+A*iLabX)+sqrt(d);
         y1=pow(A,2)*iLabY-B*(C+A*iLabX)-sqrt(d);

         x1=(-(B/A)*y1)-(C/A);
         x2=(-(B/A)*y2)-(C/A);


         if(x1==x2 && y1==y2)
          peres=1;
         else
          peres=2;

        switch (peres) {
           case 1:    ShowMessage("Одна точка пересечения в ["+(String)x1+","+(String)y1+"]"); break;
           case 2:    ShowMessage("Две точки пересечения в ["+(String)x1+","+(String)y1+"] и ["+(String)x2+","+(String)y2+"]" ); break;
        }
     }

у меня iLabX, iLabY координаты центра круга и iLabR - радиус, все остальное это отрезок.

Но результат все равно не верный

Это сообщение отредактировал(а) leporel - 3.7.2010, 05:16
PM MAIL   Вверх
leporel
Дата 3.7.2010, 14:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 109
Регистрация: 12.2.2008

Репутация: нет
Всего: -1



Код

  k=abs((iLabY1-iLabY2)/(iLabX2-iLabX1));
  b=iLabY1-k*iLabX1;

  a1 = 1+k*k;
  b1 = -2*iLabX + 2*k*b - 2*k*iLabY;
  c1 = b*b + iLabX*iLabX - 2*b*iLabY + iLabY*iLabY - iLabR*iLabR;

  d = pow(b1,2)-4*a1*c1;

   x1=(-b1-sqrt(d))/(2*a1);
   x2=(-b1+sqrt(d))/(2*a1);

   y1=k*x1+b;
   y2=k*x2+b;


Вообщем работает криво, если X1>Y1, то получается точка самой вершины окружности. И прочие махинации с координатами выдают неверные значения, только если X1<Y1 показываються верные значения. И если 1 координата положительная(X1), а другая нет(Y1) тоже фигня получается.
В том числе вычисление k не всегда получается, может делиться на ноль. Результат такойже как из алгаритма первого поста.

Ещё нашел вот такое описание - http://zvn.uriit.ru/Collection/Books/AndG2.pdf но не знаю как найти координаты после определения растояния P1P2.

ЗЫ Нашел как найти точки пресечения если центр круга в начале координат http://e-maxx.ru/algo/circle_line_intersection. Работает, и можно по этому алгоритму как-то сместить точки в зависимости от центра координат?

Это сообщение отредактировал(а) leporel - 3.7.2010, 18:22
PM MAIL   Вверх
mes
Дата 3.7.2010, 19:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(leporel @  3.7.2010,  13:54 Найти цитируемый пост)
Работает, и можно по этому алгоритму как-то сместить точки в зависимости от центра координат?

можно.. смещаете все координаты так, как если бы начало координат проходило бы через центр круга, а после возвращаете в исходное.



--------------------
PM MAIL WWW   Вверх
leporel
Дата 3.7.2010, 20:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 109
Регистрация: 12.2.2008

Репутация: нет
Всего: -1



Не это не вариант так делать у меня. Можите помочь с алгоритмом  который тут описан  http://zvn.uriit.ru/Collection/Books/AndG2.pdf ?
PM MAIL   Вверх
leporel
Дата 3.7.2010, 21:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 109
Регистрация: 12.2.2008

Репутация: нет
Всего: -1



Сделал через смещение, вроде работает, всем спасибо.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0509 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.