![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как нарисовать дугу эллипса???
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]задача недоопределена - существует не один эллипс, который можно провести через эти точки