Ищете способ изменить ориентацию панорамирования/наклона обратно на x, y

#java #math #trigonometry

Вопрос:

У меня есть что-то вроде следующего: Введите x, y и h, чтобы получить ориентацию панорамирования и наклона

         double dz = Math.sqrt( x*x   y*y );
        double rotPan = Math.toDegrees(Math.atan(x / y));
        double rotTilt = Math.toDegrees(Math.atan( h / dz ));
 

Можно ли обратить вспять эффект математики только с помощью h, заданного в начальной точке, и достичь начальных значений x и y?

Комментарии:

1. Помимо вашего вопроса: используйте Math.hypot(x, y) вместо Math.sqrt(x * x y * y) и Math.atan2(x, y) вместо Math.atan(x / y) (то же самое для другого atan).

2. Тх, я их поменял. Все еще заинтересован в обратном к x/y 🙂

3. Это просто перестановка уравнений. Сделайте это на бумаге, это будет намного проще.

Ответ №1:

 double x = dz * Math.sin(Math.toRadians(rotPan)); 
double y = dz * Math.cos(Math.toRadians(rotPan));
 

К сожалению, полностью восстановить исходные значения не представляется возможным.

Например, x = 2 и y = 5 дадут вам точно такой же dz, rotPan (и rotTilt, который не нужен), как x = -2 и y = -5. Поэтому лучшее, что вы можете сделать, — это восстановить (x, y) с возможным изменением знака для обеих координат. Кстати, вы могли бы избежать этой проблемы, если бы использовали функцию atan2 вместо atan:

 double dz = Math.hypot(x, y);
double rotPan = Math.toDegrees(Math.atan2(x, y));
double rotTilt = Math.toDegrees(Math.atan2(h, dz));
 

Если вы используете приведенные выше формулы для расчета rotPan и rotTilt, то формулы в верхней части моего поста всегда будут давать вам начальные координаты (с ограничениями числовых ошибок).

Комментарии:

1. Да, теперь это работает, спасибо. Придется поменять cos на x и sin на y, но теперь это работает как зачарованное. Это легко, если вы знаете, как 😉

Ответ №2:

Все, что вам нужно сделать, это переставить уравнения.

         double dz = Math.sqrt( x*x   y*y );
        double rotPan = Math.toDegrees(Math.atan(x / y));
        double rotTilt = Math.toDegrees(Math.atan( h / dz ));
 

Учитывая rotTilt , что вы можете рассчитать соотношение h к dz :

 double hOverDz = Math.tan(Math.toRadians(rotTilt));
 

Так что , если вы знаете h , вы можете рассчитать dz :

 dz = h / Math.tan(Math.toRadians(rotTilt));
 

Учитывая rotPan , что вы можете рассчитать соотношение x к y :

 double xOverY = Math.tan(Math.toRadians(rotPan));
 

так:

 x = y * xOverY;
 

Подзаголовок и перестановка:

 dz = sqrt(y^2 * xOverY^2   y*y)
   = sqrt((xOverY^2   1) * y*y)
dz = y * sqrt(1   xOverY^2) 

y  = dz / sqrt(1   xOverY^2)
   = h / (tan(rotTilt) * sqrt(1   xOverY^2))

y  = h / tan(rotTile) * sqrt(1   tan(rotPan)^2))
 

следовательно

 x  = y * xOverY
   = (h / tan(rotTile) * sqrt(1   tan(rotPan)^2))) * tan(rotPan)
 

Комментарии:

1. Это было нелегко понять, потому что я не математик, но я думаю, что у меня есть решение.

Ответ №3:

После ввода информации от Энди Тернера и выяснения того, что именно это означает, я получил:

     double dz = h / Math.tan(Math.toRadians(rotTilt));
    double xOverY = Math.tan(Math.toRadians(rotPan));
    double x = Math.round(dz / Math.sqrt(1   xOverY*xOverY));
    double y = Math.round(x * xOverY);

    if (pan > 90 || pan < 0) { x *=-1; y *=-1; }    // sign correction if angel > 90 or < 0
 

Я не знаю, есть ли другой способ из-за неправильного результата, если ангел > 90 или >

ПРАВКА: Хорошо, это не работает. Если я поставлю rotPan = 90 и rotTilt = любой, dx и dy всегда будут равны 0

Я не понимаю вашего способа решения или что-то не так.

Комментарии:

1. Если rotTilt = 90, это означает, что арктан h/dz равен 90 градусам, но это означает, что h/dz-положительная бесконечность. Поэтому неудивительно, что это означает, что dz = 0, поэтому и dx, и dy являются нулями. Другими словами, вы не можете получить rotTilt = 90 для любых ненулевых dx и dy (ну, если только h не является положительной бесконечностью….)

2. Моя ошибка: Я имею в виду ротПан, а не ротТилт.