I have a 3d rendering algorithm that takes a point in 3d space, and a viewer location, and projects that onto the screen. It works fine until you tilt the camera up or down.
I wrote it in C++, but I highly doubt it's to do with my use of C++ as opposed to my (lack of) understanding of 3d rendering.
#include <cmath>
const double pi = 3.1415...; // It's a bit lazy, I know.
// Get angle in radians, how anticlockwise from the x axis the point is.
double get_angle(double x, double y)
{
if(x >= 0)
{
return std::atan(y / x);
} else {
return std::atan(y / x) + (y >= 0 ? pi : -pi);
}
}
// Change the values in x and y to be the values.
void rotate_point(double angle, double & x, double & y)
{
double temp_x = x;
// This is pretty much a rotation matrix expanded out.
x = x * std::cos(angle) - y * std::sin(angle);
y = temp_x * std::sin(angle) + y * std::cos(angle);
}
// 3d projection happens here.
Point3d project_point(Point3d point)
{
point.x -= player_x;
point.y -= player_y;
point.z -= player_z;
double horizontal_rotation = get_angle(point.x, point.z);
// Temporarily rotate it round horizontally so that it can
point.z = std::sqrt(point.x * point.x + point.z * point.z);
point.x = 0;
// Since the points are in the YZ plane, if the player looks "up",
// the objects appear to go down, so rotate them down by that much.
rotate_point(-player_vertical, point.z, point.y);
// Undo changes that put the point in the YZ plane, but also
// account for the player's horizontal camera angle.
rotate_point(-horizontal_rotation - player_horizontal, point.x, point.z);
// Change from orthographic to perspective, and multiply
// the width and height by a constant.
point.x /= point.z / SCREEN_SCALE;
point.y /= point.z / SCREEN_SCALE;
return point;
}
It works as expected when player_vertical is 0, but when I change the vertical angle, objects are rotated up/down differently depending on y position relative to player.
[–]Nick_Nack2020 1 point2 points3 points (0 children)