Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.08.28;
Скачать: CL | DM;

Вниз

Построение дуги между двумя точками   Найти похожие ветки 

 
dr Tr0jan ©   (2005-04-17 09:19) [0]

Подскажите пожалуйста алгоритм построения дуги между двумя точками (со случайным или задаваемым радиусом кривизны). А то по дискретке задали смоделировать граф по матрице инцидентности,  а дугу построить не могу.


 
MBo ©   (2005-04-17 09:39) [1]

рисовать - TCanvas.Arc или PolyBezier
или непонятно вычисление параметров дуги?
Центр окружности получается решением системы уравнений (если заданы 2 точки и радиус - получится 2 решения)


 
dr Tr0jan ©   (2005-04-17 10:19) [2]

Непонятно вычисление параметров дуги.
В параметрах функции TCanvas.Arc() нет координаты центра.


 
Anatoly Podgoretsky ©   (2005-04-17 10:23) [3]

dr Tr0jan ©   (17.04.05 10:19) [2]
А если внимательно прочитать справку?


 
dr Tr0jan ©   (2005-04-17 10:48) [4]

И если внимательно, тоже.


 
dr Tr0jan ©   (2005-04-17 10:56) [5]

Точнее кординаты центра я вижу в справке. Мне бы алгоритм работающий. Тем более дугу можно задавать образованную из эллипса, оси которого паралелльны осям координат.
Я так думаю, что придется с помощью PolyBezier() создавать дугу. А как бы найти функциональную зависимость для построения дуги.


 
MBo ©   (2005-04-17 11:21) [6]


procedure CalcBezierArc(CX, CY, rx, ry: Integer;
 StartAngle, SweepAngle: Double; var BezPt: TPoint);
//C-Pascal translation from Feng Yuan book with correction of source errors
var
 P: PPtsArr;
 i: Integer;
 x0, y0, tx, ty, sn, cs: Double;
 Px, Py: array[0..3] of Double;
begin
 P := PPtsArr(@BezPt);
 //calculates control points for Bezier approx. of arc with radius=1,
 //circle center at (0,0), middle of arc at (1,0)
 y0 := Sin(SweepAngle / 2);
 x0 := Cos(SweepAngle / 2);
 tx := (1 - x0) * 4 / 3;
 ty := y0 - tx * x0 / y0;
 Px[0] := x0;
 Py[0] := -y0;
 Px[1] := x0 + tx;
 Py[1] := -ty;
 Px[2] := x0 + tx;
 Py[2] := ty;
 Px[3] := x0;
 Py[3] := y0;

 //rotation and translation of control points
 sn := Sin(StartAngle + SweepAngle / 2);
 cs := Cos(StartAngle + SweepAngle / 2);
 for i := 0 to 3 do
 begin
   P[i].X := CX + Round(RX * (Px[i] * cs - Py[i] * sn));
   P[i].Y := CY + Round(RY * (Px[i] * sn + Py[i] * cs));
 end;
end;



 
dr Tr0jan ©   (2005-04-17 12:14) [7]

Кричит на  "P: PPtsArr;" - мол неизвестный тип.


 
MBo ©   (2005-04-17 12:47) [8]

TPtsArr=array[0..3] of TPoint;
PPtrSrr=^TPtsArr;

или вместо var BezPt: TPoint можешь просто массив точек передавать


 
Anatoly Podgoretsky ©   (2005-04-17 12:48) [9]

Ну там же описано, как пользоваться и пример есть и откуда центр берется.


 
dr Tr0jan ©   (2005-04-17 12:57) [10]

> Ну там же описано, как пользоваться и пример есть и откуда центр берется.
А повернуть то его все-равно не получится.


 
dr Tr0jan ©   (2005-04-17 13:00) [11]

MBo ©   (17.04.05 12:47) [8]
А пример использования можно? А то у меня что AccessViolation прет.


 
MBo ©   (2005-04-17 13:21) [12]

>AccessViolation прет.
Не у свой памяти, значит, обращаешься

procedure TForm1.Button1Click(Sender: TObject);
var
 Pts:TPtsArr;
begin
CalcBezierArc(100,100,80,80,Pi/6,Pi/4,Pts[0]);
Canvas.PolyBezier(Pts);
end;


 
dr Tr0jan ©   (2005-04-17 14:04) [13]

Я все равно что-то не врубаюсь, как применит эту функции для решения моей задачи. Может быть я вопрос не правильно задал?

Вопрос: имеются две точки на плоскости, из одной точки в другую необходимо провести кривую заданного радиуса кривизны.


 
XProger ©   (2005-04-17 15:20) [14]

x^2 + y^2 = r^2


 
dr Tr0jan ©   (2005-04-18 00:59) [15]

Удалено модератором


 
programania ©   (2005-04-18 02:34) [16]


procedure TForm1.Timer1Timer(Sender: TObject);
var min,z,y,x,r,sx,mx,sy,my,x1,y1,x2,y2:integer;
begin
//точки и радиус:
x1:=100;y1:=300;   x2:=500;y2:=100; r:=230;

timer1.enabled:=false;
min:=$7FFFFFFF;

if r*2<sqrt(sqr(x1-x2)+sqr(y1-y2)) then begin
 showMessage("Радиус не может быть меньше расстояния между точками/2");
 halt;
end;
//поиск смещения центра my mx
for sy:=-1000 to +1000 do
for sx:=-1000 to +1000 do begin
 z:=abs(sqr(y1+sy)+sqr(x1+sx)-sqr(r))+abs(sqr(y2+sy)+sqr(x2+sx)-sqr(r));
 if (z<min) then begin min:=z; mx:=sx; my:=sy end;
end;

//рисование
for x:=x1 to x2 do canvas.Pixels[x,-trunc(my+sqrt(sqr(r)-sqr(x+mx)))]:=0;
for x:=x2 to x1 do canvas.Pixels[x,-trunc(my+sqrt(sqr(r)-sqr(x+mx)))]:=0;
for y:=y2 to y1 do canvas.Pixels[-trunc(mx+sqrt(sqr(r)-sqr(y+my))),y]:=0;
for y:=y1 to y2 do canvas.Pixels[-trunc(mx+sqrt(sqr(r)-sqr(y+my))),y]:=0;

canvas.Brush.color:=$FF;
canvas.fillRect(rect(x1-4,y1-4,x1+4,y1+4));
canvas.fillRect(rect(x2-4,y2-4,x2+4,y2+4));

end;


уравнение дуги sqr(r)=sqr(x+sm)+sqr(y+sm);
Для элипса добывьте множитель к y


 
dr Tr0jan ©   (2005-04-18 06:45) [17]

XProger ©   (17.04.05 15:20) [14]
Че за оффтоп?


 
dr Tr0jan ©   (2005-04-18 06:51) [18]

programania ©   (18.04.05 02:34) [16]
Большое спасибо.



Страницы: 1 вся ветка

Текущий архив: 2005.08.28;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.083 c
4-1120850307
DelBoy
2005-07-08 23:18
2005.08.28
Как мне окно Word открыть в форме Делфи


9-1115531873
Kobik
2005-05-08 09:57
2005.08.28
DXSound 8


1-1123429873
BackGround
2005-08-07 19:51
2005.08.28
Socket.Data


4-1121073249
Вт
2005-07-11 13:14
2005.08.28
Настройка экрана


1-1123054531
clickmaker
2005-08-03 11:35
2005.08.28
Диагональная линия через весь QuickReport