[WIP] Add Camera

This commit is contained in:
2024-02-23 22:26:38 +01:00
parent 9b85b5940a
commit 11890d6273
5 changed files with 227 additions and 0 deletions

View File

@@ -9,6 +9,7 @@ add_definitions(--coverage)
add_library(raytracing add_library(raytracing
src/camera.cpp
src/canvas.cpp src/canvas.cpp
src/color.cpp src/color.cpp
src/common.cpp src/common.cpp

View File

@@ -25,6 +25,7 @@
#pragma once #pragma once
#include "camera.h"
#include "canvas.h" #include "canvas.h"
#include "color.h" #include "color.h"
#include "common.h" #include "common.h"

96
raytracing/src/camera.cpp Normal file
View File

@@ -0,0 +1,96 @@
/*!
* camera.cpp
*
* Copyright (c) 2024, NADAL Jean-Baptiste. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*
* @Author: NADAL Jean-Baptiste
* @Date: 23/02/2024
*
*/
// This is an independent project of an individual developer. Dear PVS-Studio, please check it.
// PVS-Studio Static Code Analyzer for C, C++, C#, and Java: http://www.viva64.com
/* ------------------------------------------------------------------------- */
#include <cmath>
#include "camera.h"
using namespace Raytracer;
/* ------------------------------------------------------------------------- */
Camera::Camera(uint16_t a_h_size, uint16_t a_v_size, double a_field_of_view) :
m_h_size(a_h_size),
m_v_size(a_v_size),
m_field_of_view(a_field_of_view),
m_half_width(0),
m_half_height(0),
m_pixel_size(0)
{
double the_half_view = tan(m_field_of_view / 2);
double the_aspect_ratio = (double)m_h_size / m_v_size;
if (the_aspect_ratio >= 1)
{
m_half_width = the_half_view;
m_half_height = the_half_view / the_aspect_ratio;
}
else
{
m_half_width = the_half_view * the_aspect_ratio;
m_half_height = the_half_view;
}
m_pixel_size = ceil(((m_half_width * 2) / m_h_size) * 100) / 100;
}
/* ------------------------------------------------------------------------- */
uint16_t Camera::hsize(void) const
{
return m_h_size;
}
/* ------------------------------------------------------------------------- */
uint16_t Camera::vsize(void) const
{
return m_v_size;
}
/* ------------------------------------------------------------------------- */
double Camera::field_of_view(void) const
{
return m_field_of_view;
}
/* ------------------------------------------------------------------------- */
Matrix &Camera::transform(void)
{
return m_transform;
}
/* ------------------------------------------------------------------------- */
double Camera::pixel_size(void)
{
return m_pixel_size;
}

63
raytracing/src/camera.h Normal file
View File

@@ -0,0 +1,63 @@
/*!
* camera.h
*
* Copyright (c) 2024, NADAL Jean-Baptiste. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*
* @Author: NADAL Jean-Baptiste
* @Date: 23/02/2024
*
*/
#ifndef _RAYTRACER_CAMERA_H
#define _RAYTRACER_CAMERA_H
/* ------------------------------------------------------------------------- */
#include <cstdint>
#include "matrix.h"
/* ------------------------------------------------------------------------- */
namespace Raytracer
{
class Camera
{
public:
Camera(uint16_t a_h_size, uint16_t a_v_size, double a_field_of_view);
uint16_t hsize(void) const;
uint16_t vsize(void) const;
double field_of_view(void) const;
Matrix &transform(void);
double pixel_size(void);
private:
uint16_t m_h_size;
uint16_t m_v_size;
double m_field_of_view;
Matrix m_transform;
double m_half_width;
double m_half_height;
double m_pixel_size;
};
}; // namespace Raytracer
#endif /* _RAYTRACER_CAMERA_H */

View File

@@ -503,3 +503,69 @@ SCENARIO("An arbitrary view transformation", "[features/transformations.feature]
} }
} }
} }
/* ------------------------------------------------------------------------- */
SCENARIO("Constructing a camera", "[features/camera.feature]")
{
GIVEN("hsize <- 160")
{
uint16_t hsize = 160;
AND_GIVEN("vsize <- 120")
{
uint16_t vsize = 120;
AND_GIVEN("field_of_view <- pi / 2")
{
double field_of_view = std::numbers::pi / 2;
WHEN("c <- camera(hsize, vsize,field_of_view)")
{
Camera c(hsize, vsize, field_of_view);
THEN("c.hsize = 160")
{
REQUIRE(c.hsize() == 160);
}
AND_THEN("c.vsize = 120")
{
REQUIRE(c.vsize() == 120);
}
AND_THEN("c.field_of_view = pi / 2")
{
REQUIRE(c.field_of_view() == std::numbers::pi / 2);
}
AND_THEN("c.transform = identity_matrix")
{
REQUIRE(c.transform() == Matrix::identity());
}
}
}
}
}
}
/* ------------------------------------------------------------------------- */
SCENARIO("The pixel size for a horizontal canvas", "[features/camera.feature]")
{
GIVEN("c <- camera(200, 125, pi/2)")
{
Camera c(200, 125, std::numbers::pi / 2);
THEN("c.pixel_size = 0.01")
{
REQUIRE(c.pixel_size() == 0.01);
}
}
}
/* ------------------------------------------------------------------------- */
SCENARIO("The pixel size for a vertical canvas", "[features/camera.feature]")
{
GIVEN("c <- camera(125, 200, pi/2)")
{
Camera c(125, 200, std::numbers::pi / 2);
THEN("c.pixel_size = 0.01")
{
REQUIRE(c.pixel_size() == 0.01);
}
}
}