Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Как нарисовать дугу эллипса???


Ivanov I ©   (2002-04-19 15:29:00) 

Извиняюсь за простой вопрос но
Есть такая задача:
надо нарисовать дугу эллипса по 3 точкам.(начало конец центр),
не используя canvas.arc , т.е. по точкам
Помогите!!


Andrey007   (2002-04-22 13:46:00) [1]

Небольшое уточнение - эта функция возвращает не дугу только, а дугу вместе с центром. Чтобы она возвращала только дугу, надо убрать строчку Li.Add(Centre);


Andrey007   (2002-04-22 13:41:00) [2]

type
Point=class
fi,l: Extended;
end;
Vector=record
x,y,z: Extended
end;

function Sign(a: Real): ShortInt;
begin
if a>0 then result:=1 else if a<0 then result:=-1 else result:=0
end;

function CalculateEllips(Centre: Point; R1,R2,Azimut,BeginAngle,EndAngle: Real;
Clock: Boolean): TList; // Clock - признак рисования от меньшего угла к большему или наоборот
const rz=6372.9; // радиус сферы Каврайского в км
var fi,la,delta,a,be,en: Extended;
ek,e3,e0,em,egr: Vector;
p: Point;
i: Cardinal;
Li: TList;
begin
Result:=nil;
if (R1<=0) or (R2<=0) then Exit;
Li:=TList.Create;
Li.Add(Centre);
fi:=Centre.fi*pi/180; // перевод градусов в радианы
la:=Centre.l*pi/180;
e0.x:=cos(la)*cos(fi); em.x:=-sin(la);
e0.y:=sin(la)*cos(fi); em.y:=cos(la);
e0.z:=sin(fi); em.z:=0;
e3:=VectPr(e0,em);
i:=0;
if BeginAngle>EndAngle then //1
begin
if Clock then // От меньшего к большему
begin
be:=EndAngle*pi/180;
en:=BeginAngle*pi/180
end
else
begin
be:=BeginAngle*pi/180;
en:=EndAngle*pi/180+2*pi
end
end
else if Clock then // От большего к меньшему
begin
be:=BeginAngle*pi/180;
en:=EndAngle*pi/180
end
else
begin
be:=EndAngle*pi/180;
en:=BeginAngle*pi/180+2*pi
end;
repeat
p:=Point.Create;
a:=Be+(i-Azimut)*pi/180;
delta:=R1*R2*sqrt((1+sqr(Tan(a)))/(R2*R2+sqr(R1*Tan(a))))/rz;
a:=a+Azimut*pi/180;
ek.x:=e3.x*cos(a)+em.x*sin(a); egr.x:=e0.x*cos(delta)+ek.x*sin(delta);
ek.y:=e3.y*cos(a)+em.y*sin(a); egr.y:=e0.y*cos(delta)+ek.y*sin(delta);
ek.z:=e3.z*cos(a)+em.z*sin(a); egr.z:=e0.z*cos(delta)+ek.z*sin(delta);
p.fi:=ArcSin(egr.z);
if egr.x>0 then p.l:=ArcSin(egr.y/cos(p.fi))
else if egr.x<0 then p.l:=pi-Abs(ArcSin(egr.y/cos(p.fi)))*Sign(egr.y)
else if egr.y<0 then p.l:=-pi/2
else p.l:=pi/2;
p.l:=p.l*180/pi;
p.fi:=p.fi*180/pi;
Li.Add(p); inc(i)
until a>En;
result:=Li
end;

Эта функция возвращает список с координатами точек дуги эллипса на шаре, аппрокисмирующем Землю (сфера Каврайского). Если убрать проецирование на шар, то получится то, что Ivanov I просил. Правда для использования этой процедуры ему надо будет определить градусную меру начального и конечного углов и угол наклона эллипса в градусах (Azimut). Предполагается, что координаты центра заданы как широта и долгота, причём дробная часть не в минутах, а в десятичных долях. Соответственно, и на выходе данные в таком же формате. Дуга эллипса считается с шагом 1 градус.


Donal_Graeme   (2002-04-20 18:03:00) [3]

2 Mbo:
немного с запозданием, но - именно по той формулировке вопроса - по трём точкам - ты прав, неопределённость.
Именно поэтому я подумал, что автор просто хотел нарисовать дугу эллипса, не пользуясь стандартными средствами, зная центр, оба радиуса и углы начала и конца.


Ivanov I   (2002-04-20 09:31:00) [4]

Большое спасибо, я уже понял


MBo   (2002-04-20 00:38:00) [5]

>annton
окружность - ОДНА
дуг ЭЛЛИПСОВ - много


annton   (2002-04-20 00:21:00) [6]

Для этого нужно найти координаты точек(а через эти точки можно провести 4 дуги) центрров двух окружностей проходящих через эти точки.
Для этого, вспоминая математику и геометрию, нужно решить систему квадратных уравнений в общем виде - это уравнения окружностей с центрами в твоих точках и одинаковым радиусом. Точка пересечения этих окружностей и будет центром НУЖНОЙ окружности, зная которую можно провести Arc(...).
(a1-x1)^2+(b1-y1)^2=R^2
(a2-x2)^2+(b2-y2)^2=R^2

Если влом решать, пиши на annton@rambler.ru пришлю алгоритм!


ION T   (2002-04-19 21:55:00) [7]

Извиняюсь. Это я не о том алгоритме подумал..........


ION T   (2002-04-19 21:54:00) [8]

Кжется можно просто спроэктировать "среднюю" точку (В) на прямую АС..........


MBo   (2002-04-19 21:31:00) [9]

>ION T
неважно. если задан прямоугольник, в двух смежных углах которого начало и конец дуги, а ее середина касается противоположной стороны, то этого мало.


ION T   (2002-04-19 21:27:00) [10]

Может имелась в виду середина дуги а не диаметра........


MBo   (2002-04-19 17:26:00) [11]

>Donal_Graeme
трех точек, две из которых на одной высоте (предполагаю, именно это имелось в виду), недостаточно для определения эллипса. Автор не уточнил расположения.


Donal_Graeme   (2002-04-19 17:17:00) [12]

ищи алгоритм Брезенхема, либо же по формуле эллипса.


MBo   (2002-04-19 16:38:00) [13]

задача недоопределена - существует не один эллипс, который можно провести через эти точки


Наверх

Титульная страница Поиск, карта сайта Написать письмо