Вычислительная геометрия (Даны координаты центра, R окружности, координаты точки вне окруж-ти. Найти точку пересечения одной из касательных с окруж-ю)

Даны координаты центра (xc,yc) и радиус R окружности, координаты точки (x,y) вне окружности. Найти точку пересечения одной из касательных с окружностью. Формат входных данных: Пять вещественных чисел xc yc R x y — координаты центра и радиус окружности, координаты точки. Формат выходных данных: В первой строке одно число К, равное количеству точек пересечения касательных к окружности из заданной точки с самой окружностью. Далее в К строках координаты самих точек. Пример: input.txt output.txt 1 1 1 2 2 1.00 2.00хелп с решение, пожалуйста =(
2 ответа

Радиус окружности (R), прямая соединяющая центр и заданную точку a=sqrt((xc-x)*(xc-x)+(yc-y)*(yc-y)) и касательная к окружности b образуют прямоугольный треугольник ( a - гипотенуза). b=sqrt(a*a-R*R) Остается только решить систему уравнений (x-x0)*(x-x0)+(y-y0)*(y-y0)=b*b (xc-x0)*(xc-x0)+(yc-y0)*(yc-y0)=R*R


bolabol,
// помощь.cpp: определяет точку входа для консольного приложения.
//
 
#include "stdafx.h"
#include <conio.h>
#include <math.h>   
 
void ZapolnenieDannih();
 
FILE *fi=fopen("C:\\Example\\in.txt","rb");
FILE *fo=fopen("C:\\Example\\out.txt","wb");
****** Xc,Yc,R,Xo,Yo;
****** Xk1,Yk1;
****** Xk2,Yk2;
****** A,B,C,k1,k2;
int var=0;
long n;
 
int main()
{
    ZapolnenieDannih();
    if      ((Xo-Xc)*(Xo-Xc)+(Yo-Yc)*(Yo-Yc)<R*R)   //если точка лежит внутри окружности, то вывести сообщение об отсутствии касательных.
    {
        fprintf(fo,"Tochka lejit vnutri okrujnosti. Kasatel`nih ne sushestvuet.");
        return 0;
    }
    else if ((Xo-Xc)*(Xo-Xc)+(Yo-Yc)*(Yo-Yc)==R*R)  //если точка принадлежит окружности, то вывести сказать об этом и закончить работу программы.
    {
        fprintf(fo,"Tochka lejit na okrujnosti.");
        return 0;
    }
    else if (abs(Xo-Xc)==R)                         //если координата Xo=Xc-R или Xo=Xc+R, то касательная параллельна (O;Y) и проходит через точку (Xo;Yc)
    {
        fprintf(fo,"%.3lf %.3lf %.3lf %.3lf %.3lf %.3lf %.3lf\n",Xc,Yc,R,Xo,Yo,Xo,Yc);
        return 0;
    }
    else if (abs(Yo-Yc)==R)                         //если координата Yo=Yc-R или Yo=Yc+R, то касательная параллельна (O;X) и проходит через точку (Xc;Yo)
    {
        fprintf(fo,"%.3lf %.3lf %.3lf %.3lf %.3lf %.3lf %.3lf\n",Xc,Yc,R,Xo,Yo,Xc,Yo);
        return 0;
    }
    else if ((Xo-Xc)*(Xo-Xc)+(Yo-Yc)*(Yo-Yc)>R*R)   //если точка лежит вне окружности, то найти точку касания касательной с окружностью.
    {                                       
        A=2*Xc*Xo-Xc*Xc+R*R-Xo*Xo;
        B=Xc*Yc-Xc*Yo+Yo*Xo-Xo*Yc;
        C=R*R-Yc*Yc-Yo*Yo+2*Yc*Yo;
 
        k1=(-B+sqrt(B*B-A*C))/A;
        k2=-(-B+sqrt(B*B-A*C))/A;
 
        Xk1=(Xc+k1*(Yc+k1*Xo-Yo))/(k1*k1+1);
        Yk1=k1*(Xk1-Xo)+Yo;
        fprintf(fo,"%.3lf %.3lf %.3lf %.3lf %.3lf   %.3lf %.3lf\n",Xc,Yc,R,Xo,Yo,Xk1,Yk1);
 
    }
 
    //getch();
    return 0;
} 
 
void ZapolnenieDannih()
{
    fscanf(fi,"%lf",&Xc);
    fscanf(fi,"%lf",&Yc);
    fscanf(fi,"%lf",&R);
    fscanf(fi,"%lf",&Xo);
    fscanf(fi,"%lf",&Yo);
}
Для того, чтобы программа работала, необходимо создать два файла: C:\Example\in.txt C:\Example\out.txt