More drawing progress.
This commit is contained in:
parent
9168e584ef
commit
51311a2d51
@ -1,9 +1,58 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <numbers>
|
||||
|
||||
using std::numbers::pi;
|
||||
|
||||
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
|
||||
{
|
||||
uint8_t r, g, b, a;
|
||||
@ -61,6 +110,8 @@ namespace sharp
|
||||
int_rect(int left, int top, int width, int height);
|
||||
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 tr() const; // Top right
|
||||
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_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:
|
||||
const window_styles& style() const;
|
||||
|
||||
@ -16,7 +16,7 @@ protected:
|
||||
{
|
||||
constexpr int points = 5;
|
||||
|
||||
int bigRadius = 100,
|
||||
int bigRadius = 105,
|
||||
smallRadius = 60;
|
||||
|
||||
sharp::int2 center = get_size() / 2;
|
||||
@ -35,7 +35,7 @@ protected:
|
||||
{
|
||||
sharp::int2& this_point = arr[i],
|
||||
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
|
||||
|
||||
@ -3,6 +3,146 @@
|
||||
|
||||
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()
|
||||
{
|
||||
r = 0;
|
||||
@ -140,7 +280,12 @@ sharp::int_rect::int_rect(const int2 pos, const int2 size)
|
||||
width = size.x;
|
||||
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
|
||||
{
|
||||
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)
|
||||
{
|
||||
// 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),
|
||||
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;
|
||||
if (a.x < 0) a = int2(0, -a.x * slope + a.y); // Left wall truncate for A.
|
||||
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.
|
||||
else if (a.y >= height) a = int2(((height - 1) - a.y) * inv_slope + a.x, height - 1); // Top wall truncate for A.
|
||||
if (a.x < 0)
|
||||
{
|
||||
if (b.x < 0) return; // Off screen.
|
||||
|
||||
// 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.
|
||||
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.
|
||||
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),
|
||||
true_pos_b = to_screen(b);
|
||||
internal::draw_global_line(color, true_pos_a, true_pos_b);
|
||||
const int2 true_a = to_screen(a),
|
||||
true_b = to_screen(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