2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




 
 Алгоритм сопряжения прямой и дуги
Сообщение08.05.2010, 19:24 
Задали написать алгоритм сопряжения прямой и дуги (математически в виде уравнений), для дальнейшей его реализации в Lazarus IDE (бесплатная альтернатива Delphi основанная на FreePascal).
Вот как это выглядит http://www.propro.ru/graphbook/gp/ge..._02/02/02.html
С помощью выходных значений алгоритма в итоге должно строится само сопряжение.
Пользователь задает прямую и дугу (в виде части окружности).
Возник вопрос как определить координаты точки пересечения прямой и окружности.
Точка показана на скриншоте красным цветом:
Изображение
Код:
unit Unit1;

{[math]$mode objfpc}{$[/math]H+}

interface

uses
  Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
  StdCtrls, ExtCtrls, ComCtrls, TATransformations;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Edit1: TEdit;
    Edit2: TEdit;
    Edit3: TEdit;
    Edit4: TEdit;
    Edit5: TEdit;
    Edit6: TEdit;
    Edit7: TEdit;
    GroupBox1: TGroupBox;
    GroupBox2: TGroupBox;
    Image1: TImage;
    Label1: TLabel;
    Label10: TLabel;
    Label11: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    Label5: TLabel;
    Label6: TLabel;
    Label7: TLabel;
    Label8: TLabel;
    Label9: TLabel;
    StatusBar1: TStatusBar;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

var
  Form1: TForm1;
  Hmax: integer; //высота области рисования
  x1,x2,y1,y2,x3,y3,x4,y4,xo,ro,yo: integer; //координаты прямой
  k1: real; //коэффициент k первой прямой
  b1: real; //коэффициент b первой прямой
  r,ro2: integer; //радиусы

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
begin
  x1:= StrToInt(Edit1.Text);
  y1:= StrToInt(Edit2.Text);
  x2:= StrToInt(Edit3.Text);
  y2:= StrToInt(Edit4.Text);
  xo:= StrToInt(Edit5.Text);
  yo:= StrToInt(Edit6.Text);
  ro:= StrToInt(Edit7.Text);
r:=14;
x3:=x1+r;
x4:=x2+r;
y3:=y1;
y4:=y2;
ro2:=ro-r;
Image1.Picture := nil;
Hmax := Image1.Height;
Image1.Canvas.Rectangle(0, 0, Image1.Width, Image1.Height); //рисуем прямоугольник
Image1.Canvas.FloodFill(10, 10, clBlack, fsBorder); //заполняем его
Image1.Canvas.Brush.Color := clwhite; //цвет заливки
Image1.Canvas.Pen.Color := clblack; //цвет линий
Image1.Canvas.Ellipse(Round(xo - ro), Round(yo - ro),
  Round(xo + ro), Round(yo + ro));
//Окружность меньшего на r радиуса
Image1.Canvas.Ellipse(Round(xo - ro2), Round(yo - ro2),
  Round(xo + ro2), Round(yo + ro2));
Image1.Canvas.MoveTo(x1, y1);
Image1.Canvas.LineTo(x2,y2);
Image1.Canvas.MoveTo(x3, y3);
Image1.Canvas.LineTo(x4,y4);
//Form1.Canvas.Arc(450, 100, 0, 90, 50);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  close;
end;

end.

Прошу помочь

 
 
 
 Re: Алгоритм сопряжения прямой и дуги
Сообщение09.05.2010, 04:09 
Составьте систему из уравнения прямой и уравнения окружности, решите, результат запишите в исходник. :) Там, кстати, два ответа может получиться...

-- Вс май 09, 2010 07:19:08 --

Да и вообще, вот первая попавшаяся ссылка из гугля... Делов-то. :)

 
 
 
 Re: Алгоритм сопряжения прямой и дуги
Сообщение09.05.2010, 13:54 
Circiter в сообщении #317088 писал(а):
Составьте систему из уравнения прямой и уравнения окружности, решите, результат запишите в исходник. :) Там, кстати, два ответа может получиться...

-- Вс май 09, 2010 07:19:08 --

Да и вообще, вот первая попавшаяся ссылка из гугля... Делов-то. :)

Привет.
Преобразование координат прямой в уравнение вида y=kx+b я сделал. Теперь мне надо получить уравнение окружности, которое я буду приравнивать к kx+b. Как получить это уравнение, если я знаю координаты центра окружности и радиус? В итоге получится что-то типа kx+b=sqrt(r^2-x^2)?

 
 
 
 Re: Алгоритм сопряжения прямой и дуги
Сообщение09.05.2010, 17:06 
Вот нашел http://dmtsoft.ru/bn/377/as/oneaticleshablon/, вроде то что нужно.

 
 
 
 Re: Алгоритм сопряжения прямой и дуги
Сообщение09.05.2010, 21:17 
Вот что сделал:
Код:
unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
  StdCtrls, ExtCtrls, ComCtrls, TATransformations;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Edit1: TEdit;
    Edit2: TEdit;
    Edit3: TEdit;
    Edit4: TEdit;
    Edit5: TEdit;
    Edit6: TEdit;
    Edit7: TEdit;
    Edit8: TEdit;
    GroupBox1: TGroupBox;
    GroupBox2: TGroupBox;
    GroupBox3: TGroupBox;
    Image1: TImage;
    Label1: TLabel;
    Label10: TLabel;
    Label11: TLabel;
    Label12: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    Label5: TLabel;
    Label6: TLabel;
    Label7: TLabel;
    Label8: TLabel;
    Label9: TLabel;
    StatusBar1: TStatusBar;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

var
  Form1: TForm1;
  Hmax: integer; //высота области рисования
  x1,x2,y1,y2,x3,y3,x4,y4,xo,ro,yo: integer; //координаты прямой
  x5,x6,y5,y6,x7,y7,x8,y8,x9,y9: real; //координаты
  k1,k2,k3: real; //коэффициент k первой прямой
  b1,b2,b3: real; //коэффициент b первой прямой
  r,ro2: integer; //радиусы
  d,d2:real; //дискриминант
  leng:real; //радиус сопрягающего круга (дуги)

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
begin
//Конвертируем значение вводимых переменных из строкового в числовое
x1:= StrToInt(Edit1.Text);
y1:= StrToInt(Edit2.Text);
x2:= StrToInt(Edit3.Text);
y2:= StrToInt(Edit4.Text);
xo:= StrToInt(Edit5.Text);
yo:= StrToInt(Edit6.Text);
ro:= StrToInt(Edit7.Text);
r:= StrToInt(Edit8.Text);
//Параллельная прямая
x3:=x1+r;
x4:=x2+r;
y3:=y1;
y4:=y2;
//Окружность меньшего на r радиуса
ro2:=ro-r;
//Математическая часть
//Найдем координаты центра сопряжения
k1:=(y3-y4)/(x3-x4);
b1:=y3-k1*x3;
d:=Sqr(2*k1*b1-2*xo-2*yo*k1)-(4+4*sqr(k1))*(sqr(b1)-sqr(ro2)
  +sqr(xo)+sqr(yo)-2*yo*b1);
x5:=-(2*k1*b1-2*xo-2*yo*k1)+sqrt(d)/(2+2*sqr(k1));
y5:=k1*x5+b1;
{x5 и y5 кординаты центра сопряжения}
ShowMessage(FloatToStr(x5));
ShowMessage(FloatToStr(y5));
//Найдем координаты первой точки сопряжения
x6:=xo;
y6:=yo;
x7:=x5;
y7:=y5;
k2:=(y6-y7)/(x6-x7);
b2:=y6-k1*x6;
d2:=Sqr(2*k2*b2-2*xo-2*yo*k2)-(4+4*sqr(k2))*(sqr(b2)-sqr(ro2)
  +sqr(xo)+sqr(yo)-2*yo*b2);
x8:=-(2*k2*b2-2*xo-2*yo*k2)+sqrt(d2)/(2+2*sqr(k2));
y8:=k2*x5+b2;
{x8 и y8 это кординаты 1ой точки сопряжения}
ShowMessage(FloatToStr(x8));
ShowMessage(FloatToStr(y8));
//Перпендикулярная первой прямой прямая
k3:=-1/k1;
b3:=y5-k3*x5;  //y=k3*x+b3
x9:=(b1-b3)/(k1-k3);
y9:=k3*x9+b3;
leng:=sqrt(sqr(x9-x5)+sqr(y9-y5));
ShowMessage(FloatToStr(leng));

{ Код отрисовки }
Image1.Picture := nil;
Hmax := Image1.Height;
Image1.Canvas.Rectangle(0, 0, Image1.Width, Image1.Height); //рисуем прямоугольник
Image1.Canvas.FloodFill(10, 10, clBlack, fsBorder); //заполняем его
Image1.Canvas.Brush.Color := clwhite; //цвет заливки
Image1.Canvas.Pen.Color := clblack; //цвет линий
Image1.Canvas.Ellipse(Round(xo - ro), Round(yo - ro),
  Round(xo + ro), Round(yo + ro));
//Окружность меньшего на r радиуса
Image1.Canvas.Ellipse(Round(xo - ro2), Round(yo - ro2),
  Round(xo + ro2), Round(yo + ro2));
Image1.Canvas.MoveTo(x1, y1);
Image1.Canvas.LineTo(x2,y2);
Image1.Canvas.MoveTo(x3, y3);
Image1.Canvas.LineTo(x4,y4);
Image1.Canvas.MoveTo(Round(x5), Round(y5));
Image1.Canvas.LineTo(Round(x9), Round(y9));
//Form1.Canvas.Arc(450, 100, 0, 90, 50);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  close;
end;

end.

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

 
 
 
 Re: Алгоритм сопряжения прямой и дуги
Сообщение10.05.2010, 16:00 
Всё, ошибки нашел, математическую часть сделал, осталось реализовать красиво :-)

 
 
 [ Сообщений: 6 ] 


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group