Я пишу программу, которая будет вращать прямоугольную призму вокруг точки. Он обрабатывает вращение с помощью трех методов вращения, каждый из которых управляет вращением вокруг одной оси (X, Y и Z). Вот кодJava: Вращения и 3D-искажения
public void spinZ(Spin spin) {
if (x == 0 && y == 0) {
return;
}
double mag = Math.sqrt(x * x + y * y);
double pxr = Math.atan(y/x);
x = Math.cos(spin.zr + pxr) * mag;
y = Math.sin(spin.zr + pxr) * mag;
}
public void spinY(Spin spin) {
if (z == 0 && x == 0) {
return;
}
double mag = Math.sqrt(x * x + z * z);
double pxr = Math.atan(z/x);
x = Math.cos(spin.yr + pxr) * mag;
z = Math.sin(spin.yr + pxr) * mag;
}
public void spinX(Spin spin) {
if (z == 0 && y == 0) {
return;
}
double mag = Math.sqrt(y * y + z * z);
double pxr = Math.atan(z/y);
y = Math.cos(spin.xr + pxr) * mag;
z = Math.sin(spin.xr + pxr) * mag;
}
public void addSpin(Spin spin) {
spinY(spin);
spinX(spin);
spinZ(spin);
}
Спин является бесполезным класс, который хранит три двойников (которые вращение). Эти методы в основном преобразуют вращения в 2D-векторы (как я храню точки) и вращают их как таковые. Первый оператор if гарантирует, что 2D-векторы не являются величиной 0. Им разрешено, но в этом случае нет необходимости выполнять вычисления вращения. Другая часть просто обрабатывает триггер. Нижний метод просто связывает все вместе и позволяет мне быстро менять порядок вращения (потому что порядок должен и должен влиять на окончательное вращение).
Проблема заключается не в отдельных поворотах, а в том, когда они все объединяются. Я могу легко получить одно вращение вокруг одной оси для работы без искажения прямоугольной призмы. Когда я собираю их все вместе, например, если вы должны вызвать addSpin().
При вызове первой очереди призмы искажаются, когда вращение включает в себя вращение Y (если y-составляющая вращения равна нулю, а поворот вокруг оси y не должен происходить, то никаких искажений не происходит). На самом деле, если spinY() вызывается в любое время, но в последствии происходит искажение куба.
То же самое происходит и с spinZ(). Если spinZ() называется последним, куб не будет деформирован. Однако spinX() может идти куда угодно и не вызывать искажения.
Итак, вопрос в том, есть ли проблема с тем, как я двигаюсь по поворотам? Другой вопрос заключается в том, что, хотя все вращения не могут быть охвачены поворотами вдоль осей X и Y или любой другой пары различных осей (например, X и Z, или Y и Z), могут ли эти три группы собирать все вращения? Чтобы уточнить, могут ли вращения, которые не могут быть достигнуты с помощью набора оборотов вокруг осей X и Y, могут быть выполнены с помощью поворота вокруг осей X и Z или осей Y и Z?
Я доверяю среде, которую я использую для отображения призм. Это луч-трассирующее устройство, которое хорошо работает с прямоугольными призмами. Это более основанный на математике вопрос, но он имеет довольно комплексный компонент программирования.
Это некоторые параллельные вычисления, которые по-прежнему приводят к искажениям.
public void spinZ(Spin spin) {
double c = Math.cos(spin.yr);
double s = Math.sin(spin.yr);
double xp = x*c - y*s;
double yp = y*s + x*c;
x = xp;
y = yp;
}
public void spinY(Spin spin) {
double c = Math.cos(spin.yr);
double s = Math.sin(spin.yr);
double zp = z*c - x*s;
double xp = z*s + x*c;
x = xp;
z = zp;
}
public void spinX(Spin spin) {
double c = Math.cos(spin.yr);
double s = Math.sin(spin.yr);
double yp = y*c - z*s;
double zp = z*c + y*s;
y = yp;
z = zp;
}
Причина, по которой я проверяю значение 0, заключается не столько в том, что когда x и z равны, мне не нужны вычисления. Это то, что когда вы деляете 0 на 0 в java, вы получаете NaN, что заставляет задуматься. И это было бы правостороннее против левостороннего вращения, вызывающее искажения?Я бы так не подумал, но я мог ошибаться ... –
Нет, я бы предположил, что искажения происходят потому, что вы вычисляете радиальный угол, не различая (+, +) и (-, -), ни между (+, -) и (-, +) координатных пар. Я знаю, почему вы проверяете нуль, но, как я уже сказал, если вы используете вычисление матрицы вращения вместо изменения координат, у вас будут более стабильные вычисления без необходимости условий ветвления. –
Хорошо, я заменил ваши методы расчета вместо моего (модифицируя каждый из них в соответствии с матрицами вращения) и протестировал его. Призма все еще искажалась. Я вставлю адаптированные методы, чтобы убедиться, что триггер проверяет. –