Я пишу очень простой каркасный рендер в Java с использованием графики. У меня есть проблема, которую я до сих пор не смог решить. Мой вывод выглядит следующим образом: ![Incorrect Cube](https://i.stack.imgur.com/rEohB.png)
Однако я поместил тот же куб в Blender и переместил его в то же место, и он выглядел так: ![Correct cube from blender](https://i.stack.imgur.com/qtU2f.png)
Наиболее отчетливым отличием является то, что основание моего куба перекошено, а куб Блендера отображается довольно равномерно.
Похоже, что плоскости ближе становятся больше быстрее по сравнению с другими. прочьЯ вижу этот эффект при уменьшении масштаба. Какова причина этого? Я пробовал различные методы, в том числе уменьшение кода, чтобы камера не двигалась, чтобы убедиться, что у меня нет ошибок при повороте камеры, а также использование формул, описанных в Интернете, для проецирования точки.
Мой код показался мне слишком длинным для сайта, поэтому я поместил его здесь: https://pastebin.com/2huLqexm
Вот фрагмент кода камеры (я считаю виновником):
public class Camera {
public double nearDist;
public double farDist;
public Vec3 location;
public Vec3 lookAt;
public int screenWidth;
public int screenHeight;
public double right;
public double top;
public Camera(double fov, double nearDist, double farDist,
int screenWidth, int screenHeight) {
this.nearDist = nearDist;
this.farDist = farDist;
this.screenWidth = screenWidth;
this.screenHeight = screenHeight;
this.top = nearDist*Math.tan(Math.toRadians(fov/2.0));
this.right = top*((double)screenWidth/screenHeight);
}
private int[] toDevice(Vec3 in) {
double x = (in.x/right)*(screenWidth/2) + screenWidth/2;
double y = screenHeight/2 - (in.y/top)*(screenHeight/2);
int[] ret = {(int)x, (int)y};
return ret;
}
public void render(Graphics g, Object3D obj) {
for (int[] f : obj.faces) {
Polygon p = new Polygon();
for (int vi : f) {
Vec3 coord = obj.verts.get(vi);
Vec3 vert = new Vec3(-nearDist/coord.z * coord.x, -nearDist/coord.z * coord.y, 0);
int[] scr = toDevice(vert);
p.addPoint(scr[0], scr[1]);
}
g.setColor(Color.black);
g.drawPolygon(p);
}
}
}
Должно работать из коробки с javac Cube.java ; java Cube
(Powershell / Bash)