С 13 лет я играю с AMOS 3D и хочу научиться кодировать 3D-графику. Теперь, 10 лет спустя, я, наконец, думаю, что накопил достаточно математики, чтобы попробовать.
Я следовал различным учебникам и определил screenX (и screenY, соответственно) как
screenX = (pointX * cameraX) / distance
(плюс смещения и масштабирование.)
Моя проблема в том, к чему на самом деле относится переменная расстояния. Я видел расстояние, определяемое как разница в z между камерой и точкой. Однако это не может быть полностью правильным, поскольку x и y оказывают тот же эффект, что и z, на фактическое расстояние от камеры до точки. Я реализовал расстояние как фактическое расстояние, но результат дает несколько искаженную перспективу, как если бы она имела «слишком большую» перспективу.
Моя реализация "фактического расстояния" была следующей:
distance = new Vector(pointX, pointY, cameraZ - pointZ).magnitude()
Поэкспериментировав с кодом, я добавил в мое уравнение дополнительную переменную перспективный коэффициент следующим образом:
distance = new Vector(pointX * perspectiveCoefficient,
pointY * perspectiveCoefficient, cameraZ - pointZ).magnitude()
По какой-то причине, что за мной, я стремлюсь получить лучший результат, устанавливая перспективный коэффициент равным 1 / sqrt (2).
Мой трехмерный тестовый куб находится на http://vega.soi.city.ac.uk/~abdv866/3dcubetest/3dtest.svg. (протестировано в Safari и FF.) Он запрашивает у вас перспективный коэффициент, где 0 дает перспективу без учета расстояния х / у, а 1 - перспективу где x, y и z расстояние считается одинаково. По умолчанию 1 / sqrt (2). Куб можно вращать вокруг x и y с помощью клавиш со стрелками. (Для всех, кто заинтересован, соответствующий код находится в update () в файле View.js.)
Благодарен за любые идеи по этому поводу.