From adf32fdf4e10996653158853730a2e9d1bc255f3 Mon Sep 17 00:00:00 2001 From: namark <namark@disroot.org> Date: Sun, 19 May 2019 23:52:37 +0400 Subject: [PATCH] Arc function and a simple test sketch for it. --- arc.cpp | 98 ++++++++++++++++++++++++++++++++++++++++++++ common/simple_vg.cpp | 6 +++ common/simple_vg.h | 2 + 3 files changed, 106 insertions(+) create mode 100644 arc.cpp diff --git a/arc.cpp b/arc.cpp new file mode 100644 index 0000000..ff83a0e --- /dev/null +++ b/arc.cpp @@ -0,0 +1,98 @@ +/* Nothing interesting here, just testing the arc function... + * There bunch of points in top left stacked on top of each other... + * You can drag them around and see what they do I guess... + */ + +#include "common/sketchbook.hpp" + +constexpr float corner_radius = 14.f; +constexpr float2 half = float2::one(.5f); +const float tau = 2*std::acos(-1); + + +struct point +{ + enum + { + radius, + angle_start, + angle_end, + center, + + count + }; +}; + +std::array<float2, point::count> points; + +float2* dragged_point = nullptr; + +bool is_near(float2 corner, float2 position); + + +void start(Program& program) +{ + + program.key_up = [&program](scancode code, keycode) + { + switch(code) + { + case scancode::leftbracket: + case scancode::c: + if(pressed(scancode::rctrl) || pressed(scancode::lctrl)) + case scancode::escape: + program.end(); + break; + + default: break; + } + }; + + program.mouse_down = [](float2 position, auto) + { + for(int i = 0; i < point::count; ++i) + if(is_near(points[i], position)) + dragged_point = &points[i]; + }; + + program.mouse_up = [](auto, auto) + { + dragged_point = nullptr; + }; + + program.mouse_move = [](auto, float2 motion) + { + if(dragged_point) + (*dragged_point) += motion; + }; + + program.draw_loop = [](auto frame, auto) + { + + frame.begin_sketch() + .rectangle(rect{ frame.size }) + .fill(0xffffff_rgb) + ; + + const float2 angle_start = tau * points[point::angle_start]/frame.size; + const float2 angle_end = tau * points[point::angle_end]/frame.size; + frame.begin_sketch() + .arc(points[point::center], rangef{angle_start.x(), angle_end.x()}, + points[point::radius].x()) + .line_width(2).outline(0x0_rgb) + .fill(0xaaaaaa_rgb) + ; + + { auto sketch = frame.begin_sketch(); + for(int i = 0; i < point::count; ++i) + sketch.ellipse(rect{float2::one(corner_radius), points[i], half}); + sketch.line_width(1).outline(0x555555_rgb); + } + + }; +} + +bool is_near(float2 corner, float2 position) +{ + return (corner - position).magnitude() < corner_radius * corner_radius; +} diff --git a/common/simple_vg.cpp b/common/simple_vg.cpp index 4f30932..5c4ecd8 100644 --- a/common/simple_vg.cpp +++ b/common/simple_vg.cpp @@ -125,6 +125,12 @@ sketch& sketch::line(float2 from, float2 to) noexcept return *this; } +sketch& sketch::arc(float2 center, rangef angle, float radius) noexcept +{ + nvgBarc(context, center.x(), center.y(), radius, angle.lower(), angle.upper(), NVG_CW, 0); + return *this; +} + sketch& sketch::fill(const rgba_vector& color) noexcept { nvgFillColor(context, nvgRGBAf(color.r(), color.g(), color.b(), color.a())); diff --git a/common/simple_vg.h b/common/simple_vg.h index 3c41474..a44e2ed 100644 --- a/common/simple_vg.h +++ b/common/simple_vg.h @@ -16,6 +16,7 @@ namespace simple::vg using graphical::rgb_pixel; using graphical::rgba_pixel; using range2f = support::range<float2>; + using rangef = support::range<float>; using rect2f = geom::segment<float2>; using anchored_rect2f = geom::anchored_segment<float2>; @@ -90,6 +91,7 @@ namespace simple::vg sketch& ellipse(const range2f&) noexcept; sketch& rectangle(const range2f&) noexcept; sketch& line(float2 from, float2 to) noexcept; + sketch& arc(float2 center, rangef angle, float radius) noexcept; sketch& fill(const rgba_vector& color) noexcept; sketch& fill(const rgba_pixel& color) noexcept; -- GitLab