Форум: "Основная";
Текущий архив: 2013.03.22;
Скачать: [xml.tar.bz2];
ВнизПеревод из координат экрана в пространство Найти похожие ветки
← →
Alex_C (2011-03-28 10:15) [0]Надо рарисовать на экране глобус.
Для этого пользуюсь известными формулами перевода широты и долготы в XYZ:
function LatLonToXYZ(Lat, Lon: Real ): TPoint3d;
begin
Result.x := cos(Lat) * sin(Lon);
Result.y := sin(Lat);
Result.z := cos(Lat) * cos(Lon);
end;
формулой поворота
function Rotate(alf,bet,gam: real; P: TPoint3d): TPoint3d;
var
x,y,z,t: real;
begin
x:=P.x*cos(gam)-P.y*sin(gam);
y:=P.x*sin(gam)+P.y*cos(gam);
z:=P.z;
t:=x*cos(bet)-z*sin(bet);
z:=x*sin(bet)+z*cos(bet);
Result.x:=t;
Result.y:=y*cos(alf)-z*sin(alf);
Result.z:=y*sin(alf)+z*cos(alf);
end;
и последующего вывода на экран
function TForm1.LatLonToXY(Lat, Lon: extended; var Xout, Yout: longint): boolean;
var
Point3d: TPoint3d;
begin
Point3d := Rotate(alfa, beta, 0, LatLonToXYZ(Lat*pi/180, Lon*pi/180) );
Result := Point3d.z > 0;
Xout := Center.X + Round(Point3d.x*Radius);
Yout := Center.Y + Round(Point3d.y*Radius)
end;
все отлично работает - проблем нет.
Однако теперь мне необходимо осуществить обратную задачу - зная координаты мышы на экране пересчитать их в широту и долготу - никак не получается это сделать.
← →
oldman © (2011-03-28 10:48) [1]
> Result.x := cos(Lat) * sin(Lon);
> Result.y := sin(Lat);
> Result.z := cos(Lat) * cos(Lon);
Lat=arcsin(y)
Lon=arcsin(x/cos(Lat)) или Lon=arccos(z/cos(Lat))
← →
OW © (2011-03-28 12:16) [2]
> зная координаты мышы на экране пересчитать их в широту и
> долготу - никак не получается это сделать.
а должно?
← →
OW © (2011-03-28 12:17) [3]хех..должно..
допустим, у нас проекция на мир сверху, то экранные координаты соотносятся с мировыми, как (x, y, Любое).
т.е. точка по оси z, может быть где угодно
в случае с глобусом (сферой, для определенности) - в двух местах.
(Спицей протыкаем шарик и две точки имеем пересечения)
т.е. где -то в ответе корень квадратный должен быть, т.е. +- Значение.
← →
Alex_C (2011-03-28 13:55) [4]То oldman: эх если бы все так было просто :) Ты не учитываешь ротацию!
> а должно?
Да, должно. Но, насколько я знаю, формула достаточно сложная, но она существует, т.к. подобного рода программы существуют. Есть и платный анаголичный компонент для Дельфи TGlobe.
← →
MBo © (2011-03-28 14:35) [5]1. Проекция из экранных координат на переднюю полусферу (x, y сохраняются, z по ним рассчитывается)
2. Rotate на отрицательные значения alf,bet,gam
3. Перевод в Lat/Lon
← →
имя (2011-03-28 15:04) [6]Удалено модератором
← →
CrytoGen (2011-03-28 21:18) [7]Лучше работайте с матрицами, проще будет обратное преобразование сделать.
← →
Alex_C (2011-03-29 16:46) [8]В общем все оказалось несколько сложнее.
Вот что я сделал:
procedure TForm1.XYToLatLon(alf, bet, gam: Extended; Xin, Yin: longint;
var Lat, Lon: extended);
var
Point3d: TPoint3d;
x, y, z: Extended;
begin
// Убираем радиус
Point3d.x := (Xin - Center.X) / Radius;
Point3d.y := (Yin - Center.Y) / Radius;
Point3d.z := Sqrt(1 - Sqr(Point3d.x) - Sqr(Point3d.y)); // Формула сферы
// Вычисляем до поворота
if alf < 0.0001 then
begin
z := Point3d.z;
y := Point3d.y;
end
else if Abs(alf-Pi/2) < 0.0001 then
begin
z := -Point3d.y;
y := Point3d.z;
end
else
begin
z := (Point3d.z * Cos(alf) - Point3d.y * Sin(alf)) / (Sqr(Cos(alf)) - Sqr(Sin(alf)));
y := (Point3d.y + z * Sin(alf)) / Cos(alf);
end;
if bet < 0.0001 then
begin
x := Point3d.x;
end
else if Abs(bet-Pi/2) < 0.0001 then
begin
x := z;
z := - Point3d.x;
end
else
begin
x := (z*Sin(bet) + Point3d.x*Cos(bet)) / (Sqr(Cos(bet)) + Sqr(Sin(bet)));
z := (z - x*Sin(bet)) / Cos(bet);
end;
Point3d.z := z;
if gam < 0.0001 then
begin
Point3d.x := x;
Point3d.y := y;
end
else if Abs(gam-Pi/2) < 0.0001 then
begin
Point3d.x := y;
Point3d.y := -x;
end
else
begin
Point3d.y := (y * Cos(gam) - x * Sin(gam)) / (Sqr(Cos(gam)) - Sqr(Sin(gam)));
Point3d.x := (x + Point3d.y * Sin(gam)) / Cos(gam);
end;
// Вычисляем широту и долготу
// if Abs(Point3d.y - Pi/2) > 0.001 then
Lat := -ArcSin(Point3d.y);
Lon := ArcSin(Point3d.x / Cos(Lat));
end;
Вроде как работает, но не правильно. Уже и все по нескольку раз проверил...
← →
MBo © (2011-03-29 19:43) [9]>Вроде как работает, но не правильно
Значит, отладка нужна.
А вот это что означает?
z := (Point3d.z * Cos(alf) - Point3d.y * Sin(alf)) / (Sqr(Cos(alf)) - Sqr(Sin(alf)));
y := (Point3d.y + z * Sin(alf)) / Cos(alf);
← →
Alex_C (2011-03-30 00:43) [10]
> А вот это что означает?
А вот именно здесь и была ошибка )))
Еще раз внимательно все проверил - после исправления этих двух строк все и заработало)))
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2013.03.22;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.069 c