Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Media";
Текущий архив: 2005.08.28;
Скачать: [xml.tar.bz2];

Вниз

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

 
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 вся ветка

Форум: "Media";
Текущий архив: 2005.08.28;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.49 MB
Время: 0.035 c
14-1122973644
12DFBDDh
2005-08-02 13:07
2005.08.28
Политкорректные сказки


8-1113715157
dr Tr0jan
2005-04-17 09:19
2005.08.28
Построение дуги между двумя точками


14-1123361147
pasha_golub
2005-08-07 00:45
2005.08.28
Горю. Проблема с SP2


1-1123175284
Андрей Молчанов
2005-08-04 21:08
2005.08.28
получить интерфейс IShellFolder


4-1121169826
Piter
2005-07-12 16:03
2005.08.28
Эмуляция нажатий клавиш





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский