ellipse.cpp 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. /* ellipse is just a trasnformed circle
  2. */
  3. #include "common/sketchbook.hpp"
  4. constexpr float corner_radius = 14.f;
  5. constexpr float2 half = float2::one(.5f);
  6. const float tau = 2*std::acos(-1);
  7. struct point
  8. {
  9. enum
  10. {
  11. center,
  12. lower,
  13. upper,
  14. count
  15. };
  16. };
  17. std::array<float2, point::count> points;
  18. float2* dragged_point = nullptr;
  19. bool is_near(float2 corner, float2 position);
  20. void start(Program& program)
  21. {
  22. program.resizable = true;
  23. program.draw_once = [](auto frame)
  24. {
  25. points[point::center] = frame.size/2;
  26. points[point::lower] = trand_float2() * frame.size;
  27. points[point::upper] = trand_float2() * frame.size;
  28. };
  29. program.key_up = [&program](scancode code, keycode)
  30. {
  31. switch(code)
  32. {
  33. case scancode::leftbracket:
  34. case scancode::c:
  35. if(pressed(scancode::rctrl) || pressed(scancode::lctrl))
  36. case scancode::escape:
  37. program.end();
  38. break;
  39. default: break;
  40. }
  41. };
  42. program.mouse_down = [](float2 position, auto)
  43. {
  44. for(int i = 0; i < point::count; ++i)
  45. if(is_near(points[i], position))
  46. dragged_point = &points[i];
  47. };
  48. program.mouse_up = [](auto, auto)
  49. {
  50. dragged_point = nullptr;
  51. };
  52. program.mouse_move = [](auto, float2 motion)
  53. {
  54. if(dragged_point)
  55. (*dragged_point) += motion;
  56. };
  57. program.draw_loop = [](auto frame, auto)
  58. {
  59. frame.begin_sketch()
  60. .rectangle(rect{ frame.size })
  61. .fill(0xffffff_rgb)
  62. ;
  63. { auto sketch = frame.begin_sketch();
  64. auto transform = geom::vector{
  65. points[point::lower],
  66. points[point::upper]
  67. } - points[point::center];
  68. auto v = float2::i();
  69. const auto dencity = 100;
  70. auto step = common::protractor<>::tau(1.f/dencity);
  71. sketch.move(transform(v) + points[point::center]);
  72. for(int i = dencity; i --> 0;)
  73. {
  74. v = common::rotate(v,step);
  75. sketch.vertex(transform(v) + points[point::center]);
  76. }
  77. sketch.fill(0xaa00aa_rgb);
  78. }
  79. // librarified
  80. // frame.begin_sketch()
  81. // .ellipse(points[point::center],
  82. // float2x2{
  83. // points[point::lower],
  84. // points[point::upper]
  85. // } - points[point::center]
  86. // )
  87. // .fill(0xaa00aa_rgb)
  88. // ;
  89. { auto sketch = frame.begin_sketch();
  90. for(int i = 0; i < point::count; ++i)
  91. sketch.ellipse(rect{float2::one(corner_radius), points[i], half});
  92. sketch.line_width(1).outline(0x555555_rgb);
  93. }
  94. };
  95. }
  96. bool is_near(float2 corner, float2 position)
  97. {
  98. return (corner - position).magnitude() < corner_radius * corner_radius;
  99. }