More drawing progress.
This commit is contained in:
parent
9168e584ef
commit
51311a2d51
@ -1,9 +1,58 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <numbers>
|
||||||
|
|
||||||
|
using std::numbers::pi;
|
||||||
|
|
||||||
namespace sharp
|
namespace sharp
|
||||||
{
|
{
|
||||||
|
enum angle_type
|
||||||
|
{
|
||||||
|
DEGREES = 10,
|
||||||
|
RADIANS = 11,
|
||||||
|
GRADIANS = 12,
|
||||||
|
TURNS = 13
|
||||||
|
};
|
||||||
|
struct angle
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
double value;
|
||||||
|
|
||||||
|
public:
|
||||||
|
angle();
|
||||||
|
angle(const angle& copy);
|
||||||
|
angle(double amount, angle_type unit);
|
||||||
|
|
||||||
|
double get(angle_type unit) const;
|
||||||
|
|
||||||
|
double degrees() const;
|
||||||
|
double radians() const;
|
||||||
|
double gradians() const;
|
||||||
|
double turns() const;
|
||||||
|
|
||||||
|
void set(double value, angle_type unit);
|
||||||
|
|
||||||
|
void degrees(double deg);
|
||||||
|
void radians(double rad);
|
||||||
|
void gradians(double grad);
|
||||||
|
void turns(double turns);
|
||||||
|
|
||||||
|
const angle operator+(const angle& other) const;
|
||||||
|
const angle operator-() const;
|
||||||
|
const angle operator-(const angle& other) const;
|
||||||
|
const angle operator*(double factor) const;
|
||||||
|
const angle operator/(double factor) const;
|
||||||
|
};
|
||||||
|
const angle operator""_deg(long double val);
|
||||||
|
const angle operator""_deg(unsigned long long val);
|
||||||
|
const angle operator""_rad(long double val);
|
||||||
|
const angle operator""_rad(unsigned long long val);
|
||||||
|
const angle operator""_grad(long double val);
|
||||||
|
const angle operator""_grad(unsigned long long val);
|
||||||
|
const angle operator""_turns(long double val);
|
||||||
|
const angle operator""_turns(unsigned long long val);
|
||||||
|
|
||||||
struct color
|
struct color
|
||||||
{
|
{
|
||||||
uint8_t r, g, b, a;
|
uint8_t r, g, b, a;
|
||||||
@ -61,6 +110,8 @@ namespace sharp
|
|||||||
int_rect(int left, int top, int width, int height);
|
int_rect(int left, int top, int width, int height);
|
||||||
int_rect(const int2 pos, const int2 size);
|
int_rect(const int2 pos, const int2 size);
|
||||||
|
|
||||||
|
static const int_rect from_corners(const int2& a, const int2& b);
|
||||||
|
|
||||||
const int2 tl() const; // Top left
|
const int2 tl() const; // Top left
|
||||||
const int2 tr() const; // Top right
|
const int2 tr() const; // Top right
|
||||||
const int2 bl() const; // Bottom left
|
const int2 bl() const; // Bottom left
|
||||||
|
|||||||
@ -72,7 +72,7 @@ namespace sharp
|
|||||||
void draw_line(const color& color, const int2& start, const int2& end);
|
void draw_line(const color& color, const int2& start, const int2& end);
|
||||||
//void draw_rect(const color& color, const int_rect& rect);
|
//void draw_rect(const color& color, const int_rect& rect);
|
||||||
|
|
||||||
//void fill_rect(const color& color, const int_rect& rect);
|
void fill_rect(const color& color, const int_rect& rect);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
const window_styles& style() const;
|
const window_styles& style() const;
|
||||||
|
|||||||
@ -16,7 +16,7 @@ protected:
|
|||||||
{
|
{
|
||||||
constexpr int points = 5;
|
constexpr int points = 5;
|
||||||
|
|
||||||
int bigRadius = 100,
|
int bigRadius = 105,
|
||||||
smallRadius = 60;
|
smallRadius = 60;
|
||||||
|
|
||||||
sharp::int2 center = get_size() / 2;
|
sharp::int2 center = get_size() / 2;
|
||||||
@ -35,7 +35,7 @@ protected:
|
|||||||
{
|
{
|
||||||
sharp::int2& this_point = arr[i],
|
sharp::int2& this_point = arr[i],
|
||||||
next_point = arr[(i + 1) % (points * 2)];
|
next_point = arr[(i + 1) % (points * 2)];
|
||||||
draw_line(0xABCDEF, this_point, next_point);
|
fill_rect(0x28b56e, sharp::int_rect::from_corners(this_point, next_point));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void tick() override
|
void tick() override
|
||||||
|
|||||||
@ -3,6 +3,146 @@
|
|||||||
|
|
||||||
using namespace sharp;
|
using namespace sharp;
|
||||||
|
|
||||||
|
using std::max;
|
||||||
|
using std::min;
|
||||||
|
|
||||||
|
static constexpr double degrees_per_turn = 360;
|
||||||
|
static constexpr double radians_per_turn = 2 * pi;
|
||||||
|
static constexpr double gradians_per_turn = 400;
|
||||||
|
|
||||||
|
sharp::angle::angle()
|
||||||
|
{
|
||||||
|
value = 0;
|
||||||
|
}
|
||||||
|
sharp::angle::angle(const angle& copy)
|
||||||
|
{
|
||||||
|
value = copy.value;
|
||||||
|
}
|
||||||
|
sharp::angle::angle(double amount, angle_type unit)
|
||||||
|
{
|
||||||
|
set(amount, unit);
|
||||||
|
}
|
||||||
|
double sharp::angle::get(angle_type unit) const
|
||||||
|
{
|
||||||
|
switch (unit)
|
||||||
|
{
|
||||||
|
case DEGREES: return degrees();
|
||||||
|
case RADIANS: return radians();
|
||||||
|
case GRADIANS: return gradians();
|
||||||
|
case TURNS: return turns();
|
||||||
|
default: return 0.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
double sharp::angle::degrees() const
|
||||||
|
{
|
||||||
|
return degrees_per_turn * value;
|
||||||
|
}
|
||||||
|
double sharp::angle::radians() const
|
||||||
|
{
|
||||||
|
return radians_per_turn * value;
|
||||||
|
}
|
||||||
|
double sharp::angle::gradians() const
|
||||||
|
{
|
||||||
|
return gradians_per_turn * value;
|
||||||
|
}
|
||||||
|
double sharp::angle::turns() const
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
void sharp::angle::set(double value, angle_type unit)
|
||||||
|
{
|
||||||
|
switch (unit)
|
||||||
|
{
|
||||||
|
case DEGREES: degrees(value);
|
||||||
|
case RADIANS: radians(value);
|
||||||
|
case GRADIANS: gradians(value);
|
||||||
|
case TURNS: turns(value);
|
||||||
|
default: return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void sharp::angle::degrees(double deg)
|
||||||
|
{
|
||||||
|
value = deg / degrees_per_turn;
|
||||||
|
}
|
||||||
|
void sharp::angle::radians(double rad)
|
||||||
|
{
|
||||||
|
value = rad / radians_per_turn;
|
||||||
|
}
|
||||||
|
void sharp::angle::gradians(double grad)
|
||||||
|
{
|
||||||
|
value = grad / gradians_per_turn;
|
||||||
|
}
|
||||||
|
void sharp::angle::turns(double turns)
|
||||||
|
{
|
||||||
|
value = turns;
|
||||||
|
}
|
||||||
|
// Doing this somewhat convoluted set system because I don't
|
||||||
|
// want to run unneccessary unit detection, I know I'm working
|
||||||
|
// with the raw turns.
|
||||||
|
const angle sharp::angle::operator+(const angle& other) const
|
||||||
|
{
|
||||||
|
angle result = angle();
|
||||||
|
result.value = value + other.value;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
const angle sharp::angle::operator-() const
|
||||||
|
{
|
||||||
|
angle result = angle();
|
||||||
|
result.value = -value;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
const angle sharp::angle::operator-(const angle& other) const
|
||||||
|
{
|
||||||
|
angle result = angle();
|
||||||
|
result.value = value - other.value;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
const angle sharp::angle::operator*(double factor) const
|
||||||
|
{
|
||||||
|
angle result = angle();
|
||||||
|
result.value = value * factor;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
const angle sharp::angle::operator/(double factor) const
|
||||||
|
{
|
||||||
|
angle result = angle();
|
||||||
|
result.value = value / factor;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
// These are shorthands.
|
||||||
|
const angle sharp::operator""_deg(long double val)
|
||||||
|
{
|
||||||
|
return angle(val, DEGREES);
|
||||||
|
}
|
||||||
|
const angle sharp::operator""_deg(unsigned long long val)
|
||||||
|
{
|
||||||
|
return angle(val, DEGREES);
|
||||||
|
}
|
||||||
|
const angle sharp::operator""_rad(long double val)
|
||||||
|
{
|
||||||
|
return angle(val, RADIANS);
|
||||||
|
}
|
||||||
|
const angle sharp::operator""_rad(unsigned long long val)
|
||||||
|
{
|
||||||
|
return angle(val, RADIANS);
|
||||||
|
}
|
||||||
|
const angle sharp::operator""_grad(long double val)
|
||||||
|
{
|
||||||
|
return angle(val, GRADIANS);
|
||||||
|
}
|
||||||
|
const angle sharp::operator""_grad(unsigned long long val)
|
||||||
|
{
|
||||||
|
return angle(val, GRADIANS);
|
||||||
|
}
|
||||||
|
const angle sharp::operator""_turns(long double val)
|
||||||
|
{
|
||||||
|
return angle(val, TURNS);
|
||||||
|
}
|
||||||
|
const angle sharp::operator""_turns(unsigned long long val)
|
||||||
|
{
|
||||||
|
return angle(val, TURNS);
|
||||||
|
}
|
||||||
|
|
||||||
sharp::color::color()
|
sharp::color::color()
|
||||||
{
|
{
|
||||||
r = 0;
|
r = 0;
|
||||||
@ -140,7 +280,12 @@ sharp::int_rect::int_rect(const int2 pos, const int2 size)
|
|||||||
width = size.x;
|
width = size.x;
|
||||||
height = size.y;
|
height = size.y;
|
||||||
}
|
}
|
||||||
|
const int_rect sharp::int_rect::from_corners(const int2& a, const int2& b)
|
||||||
|
{
|
||||||
|
int2 tl = int2(min(a.x, b.x), min(a.y, b.y));
|
||||||
|
int2 size = int2(max(a.x, b.x) - tl.x, max(a.y, b.y) - tl.y);
|
||||||
|
return int_rect(tl, size);
|
||||||
|
}
|
||||||
const int2 sharp::int_rect::tl() const
|
const int2 sharp::int_rect::tl() const
|
||||||
{
|
{
|
||||||
return int2(top, left);
|
return int2(top, left);
|
||||||
|
|||||||
@ -72,24 +72,67 @@ void window_base::draw_pixel(const color& color, const int2& win_pos)
|
|||||||
}
|
}
|
||||||
void window_base::draw_line(const color& color, const int2& pos_a, const int2& pos_b)
|
void window_base::draw_line(const color& color, const int2& pos_a, const int2& pos_b)
|
||||||
{
|
{
|
||||||
// FIXME: This causes artifacts occasionally along the top and bottom of the window.
|
|
||||||
// Why?
|
|
||||||
|
|
||||||
double slope = (double)(pos_b.y - pos_a.y) / (pos_b.x - pos_a.x),
|
double slope = (double)(pos_b.y - pos_a.y) / (pos_b.x - pos_a.x),
|
||||||
inv_slope = (double)(pos_b.x - pos_a.x) / (pos_b.y - pos_a.y); // Prevent divide by zero errors.
|
inv_slope = (double)(pos_b.x - pos_a.x) / (pos_b.y - pos_a.y); // Prevent divide by zero errors.
|
||||||
|
|
||||||
int2 a = pos_a, b = pos_b;
|
int2 a = pos_a, b = pos_b;
|
||||||
if (a.x < 0) a = int2(0, -a.x * slope + a.y); // Left wall truncate for A.
|
if (a.x < 0)
|
||||||
else if (a.x >= width) a = int2(width - 1, ((width - 1) - a.x) * slope + a.y); // Right wall truncate for A.
|
{
|
||||||
if (a.y < 0) a = int2(-a.y * inv_slope + a.x, 0); // Bottom wall truncate for A.
|
if (b.x < 0) return; // Off screen.
|
||||||
else if (a.y >= height) a = int2(((height - 1) - a.y) * inv_slope + a.x, height - 1); // Top wall truncate for A.
|
|
||||||
|
|
||||||
|
// Left wall truncate for A.
|
||||||
|
a = int2(0, -a.x * slope + a.y);
|
||||||
|
}
|
||||||
|
else if (a.x >= width)
|
||||||
|
{
|
||||||
|
if (b.x >= width) return; // Off screen.
|
||||||
|
|
||||||
|
// Right wall truncate for A.
|
||||||
|
a = int2(width - 1, ((width - 1) - a.x) * slope + a.y);
|
||||||
|
}
|
||||||
|
if (a.y < 0)
|
||||||
|
{
|
||||||
|
if (b.y < 0) return;
|
||||||
|
|
||||||
|
// Bottom wall truncate for A.
|
||||||
|
a = int2(-a.y * inv_slope + a.x, 0);
|
||||||
|
}
|
||||||
|
else if (a.y >= height)
|
||||||
|
{
|
||||||
|
if (b.y >= height) return;
|
||||||
|
|
||||||
|
// Top wall truncate for A.
|
||||||
|
a = int2(((height - 1) - a.y) * inv_slope + a.x, height - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// No checks for the other point need to be made here, because if both
|
||||||
|
// are off screen, it would have triggered in the checks above.
|
||||||
if (b.x < 0) b = int2(0, -a.x * slope + a.y); // Left wall truncate for B.
|
if (b.x < 0) b = int2(0, -a.x * slope + a.y); // Left wall truncate for B.
|
||||||
else if (b.x >= width) b = int2(width - 1, ((width - 1) - a.x) * slope + a.y); // Right wall truncate for B.
|
else if (b.x >= width) b = int2(width - 1, ((width - 1) - a.x) * slope + a.y); // Right wall truncate for B.
|
||||||
if (b.y < 0) b = int2(-a.y * inv_slope + a.x, 0); // Bottom wall truncate for B.
|
if (b.y < 0) b = int2(-a.y * inv_slope + a.x, 0); // Bottom wall truncate for B.
|
||||||
else if (b.y >= height) b = int2(((height - 1) - a.y) * inv_slope + a.x, height - 1); // Top wall truncate for B.
|
else if (b.y >= height) b = int2(((height - 1) - a.y) * inv_slope + a.x, height - 1); // Top wall truncate for B.
|
||||||
|
|
||||||
const int2 true_pos_a = to_screen(a),
|
const int2 true_a = to_screen(a),
|
||||||
true_pos_b = to_screen(b);
|
true_b = to_screen(b);
|
||||||
internal::draw_global_line(color, true_pos_a, true_pos_b);
|
internal::draw_global_line(color, true_a, true_b);
|
||||||
|
}
|
||||||
|
void window_base::fill_rect(const color& color, const int_rect& rect)
|
||||||
|
{
|
||||||
|
int2 a = rect.tl(), b = rect.br();
|
||||||
|
|
||||||
|
if (a.x < 0) a.x = 0;
|
||||||
|
else if (a.x >= width) a.x = width;
|
||||||
|
if (a.y < 0) a.y = 0;
|
||||||
|
else if (a.y >= height) a.y = height;
|
||||||
|
|
||||||
|
if (b.x < 0) b.x = 0;
|
||||||
|
else if (b.x >= width) b.x = width;
|
||||||
|
if (b.y < 0) b.y = 0;
|
||||||
|
else if (b.y >= height) b.y = height;
|
||||||
|
|
||||||
|
if (a.x == b.x || a.y == b.y) return; // Zero width or height, ignore.
|
||||||
|
|
||||||
|
const int2 true_a = to_screen(a),
|
||||||
|
true_b = to_screen(b);
|
||||||
|
internal::fill_global_rectangle(color, int_rect(true_a, true_b - true_a));
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user