From 3a800691609d2c1ffc091f29fb7452109ee60230 Mon Sep 17 00:00:00 2001 From: Andrew Golovashevich Date: Wed, 11 Dec 2024 15:40:45 +0300 Subject: [PATCH] Lab 1 / variant 1 --- programs/lab1/src/variants/common.hpp | 6 ++ programs/lab1/src/variants/variant1.cpp | 59 +++++++++- .../utilities/shapes/circle.hpp | 101 ++++++++++++++++++ 3 files changed, 163 insertions(+), 3 deletions(-) create mode 100644 programs/lab1/src/variants/common.hpp create mode 100644 utilities/include/bgtu/computer_graphics_lab_work/utilities/shapes/circle.hpp diff --git a/programs/lab1/src/variants/common.hpp b/programs/lab1/src/variants/common.hpp new file mode 100644 index 0000000..29ab537 --- /dev/null +++ b/programs/lab1/src/variants/common.hpp @@ -0,0 +1,6 @@ +#pragma once + + +namespace BGTU::ComputerGraphicsLabWork::Lab1 { + +} \ No newline at end of file diff --git a/programs/lab1/src/variants/variant1.cpp b/programs/lab1/src/variants/variant1.cpp index 44c0084..84d287b 100644 --- a/programs/lab1/src/variants/variant1.cpp +++ b/programs/lab1/src/variants/variant1.cpp @@ -1,8 +1,10 @@ #include #include #include +#include #include "../variants.hpp" #include "../sprite_data.hpp" +#include "common.hpp" namespace BGTU::ComputerGraphicsLabWork::Lab1 { namespace Variant1 { @@ -15,7 +17,7 @@ namespace BGTU::ComputerGraphicsLabWork::Lab1 { Utilities::Shapes::draw_polygon_edge( frame, {data->neg_rotated(data->radius / 2, 0), data->neg_rotated(data->radius / 2, 90), data->neg_rotated(data->radius / 2, 180), data->neg_rotated(data->radius / 2, 270),}, - 1, + 2, {255, 0, 0} ); } @@ -35,14 +37,65 @@ namespace BGTU::ComputerGraphicsLabWork::Lab1 { {-data->radius, 0}, {0, -data->radius} }, - 2, + 3, {0, 255, 255} ); } }; + class S3 : public RendererApi::Sprite> { + public: + void draw( + BGTU::ComputerGraphicsLabWork::Utilities::ZoomedVoxelPainter *frame, + const BGTU::ComputerGraphicsLabWork::Lab1::Lab1SpriteData::ShapeData *data + ) const final { + Utilities::Shapes::draw_circle_edge( + frame, + {0, 0}, + data->radius, + 5, + {0, 127, 255} + ); + } + }; + class S4 : public RendererApi::Sprite> { + public: + void draw( + BGTU::ComputerGraphicsLabWork::Utilities::ZoomedVoxelPainter *frame, + const BGTU::ComputerGraphicsLabWork::Lab1::Lab1SpriteData::ShapeData *data + ) const final { + Utilities::Shapes::draw_circle_edge( + frame, + {0, 0}, + data->radius / (2.0 * std::sqrt(2)), + 1, + {127, 127, 127} + ); + } + }; + + class S5 : public RendererApi::Sprite> { + public: + void draw( + BGTU::ComputerGraphicsLabWork::Utilities::ZoomedVoxelPainter *frame, + const BGTU::ComputerGraphicsLabWork::Lab1::Lab1SpriteData::ShapeData *data + ) const final { + auto r2 = data->radius / 2; + Utilities::Shapes::draw_polygon_edge( + frame, + { + {-r2, -r2}, + {-r2, r2}, + {r2, r2}, + {r2, -r2} + }, + 3, + {0, 255, 0} + ); + } + }; } - variant_sprites variant1 = variant_sprites::make(Variant1::S1{}, Variant1::S2{}); + variant_sprites variant1 = variant_sprites::make(Variant1::S1{}, Variant1::S2{}, Variant1::S3{}, Variant1::S4{}, Variant1::S5{}); } \ No newline at end of file diff --git a/utilities/include/bgtu/computer_graphics_lab_work/utilities/shapes/circle.hpp b/utilities/include/bgtu/computer_graphics_lab_work/utilities/shapes/circle.hpp new file mode 100644 index 0000000..4e8e148 --- /dev/null +++ b/utilities/include/bgtu/computer_graphics_lab_work/utilities/shapes/circle.hpp @@ -0,0 +1,101 @@ +#pragma once + +#include +#include + +namespace BGTU::ComputerGraphicsLabWork::Utilities::Shapes { + template + void iterate_circle_edge( + RendererApi::PointI<2>::component_t cx, RendererApi::PointI<2>::component_t cy, + RendererApi::PointI<2>::component_t r, + receiver_t receiver + ) { + RendererApi::PointI<2>::component_t x = 0, y = r; + while (x < y) { + RendererApi::PointI<2>::component_t D1 = x * x + y * y - r * r; + RendererApi::PointI<2>::component_t D2 = x * x + (y - 1) * (y - 1) - r * r; + + if (D1 > -D2) + y--; + + receiver(cx + x, cy + y); + receiver(cx + x, cy - y); + receiver(cx + y, cy + x); + receiver(cx + y, cy - x); + receiver(cx - x, cy + y); + receiver(cx - x, cy - y); + receiver(cx - y, cy + x); + receiver(cx - y, cy - x); + x++; + } + } + + + template + void iterate_circle_edge( + RendererApi::PointI<2> center, + RendererApi::PointI<2>::component_t r, + receiver_t receiver + ) { + return iterate_circle_edge(center.x, center.y, r, receiver); + } + + + template + void draw_circle_edge( + voxel_painter_t *painter, + RendererApi::PointI<2>::component_t cx, RendererApi::PointI<2>::component_t cy, + RendererApi::PointI<2>::component_t r, + double z, + RendererApi::Color::Transparent outline + ) { + iterate_circle_edge( + cx, cy, r, + [=](RendererApi::PointI<2>::component_t x, RendererApi::PointI<2>::component_t y) { painter->add_voxel(x, y, z, outline); } + ); + } + + template + void draw_circle_edge( + voxel_painter_t *painter, + RendererApi::PointI<2> center, + RendererApi::PointI<2>::component_t r, + double z, + RendererApi::Color::Transparent outline + ) { + iterate_circle_edge( + center, r, + [=](RendererApi::PointI<2>::component_t x, RendererApi::PointI<2>::component_t y) { painter->add_voxel(x, y, z, outline); } + ); + } + + template + void draw_circle_edge( + voxel_painter_t *painter, + RendererApi::PointI<2>::component_t cx, RendererApi::PointI<2>::component_t cy, + RendererApi::PointI<2>::component_t r, + double z, + RendererApi::Color::Transparent outline, + RendererApi::SpriteMetadata *owner + ) { + iterate_circle_edge( + cx, cy, r, + [=](RendererApi::PointI<2>::component_t x, RendererApi::PointI<2>::component_t y) { painter->add_voxel(x, y, z, outline, owner); } + ); + } + + template + void draw_circle_edge( + voxel_painter_t *painter, + RendererApi::PointI<2> center, + RendererApi::PointI<2>::component_t r, + double z, + RendererApi::Color::Transparent outline, + RendererApi::SpriteMetadata *owner + ) { + iterate_circle_edge( + center, r, + [=](RendererApi::PointI<2>::component_t x, RendererApi::PointI<2>::component_t y) { painter->add_voxel(x, y, z, outline, owner); } + ); + } +} \ No newline at end of file