From c8a59722432cf55309c90b678c62f52be7ae2703 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Fri, 7 Dec 2018 10:05:34 +0100 Subject: [PATCH] [python/turtle] Turtle::circle(radius, angle) --- python/port/genhdr/qstrdefs.in.h | 1 + python/port/mod/turtle/modturtle.cpp | 5 ++++ python/port/mod/turtle/modturtle.h | 1 + python/port/mod/turtle/modturtle_table.c | 2 ++ python/port/mod/turtle/turtle.cpp | 38 ++++++++++++++++++++---- python/port/mod/turtle/turtle.h | 7 +++-- 6 files changed, 46 insertions(+), 8 deletions(-) diff --git a/python/port/genhdr/qstrdefs.in.h b/python/port/genhdr/qstrdefs.in.h index d9a63131c..211824911 100644 --- a/python/port/genhdr/qstrdefs.in.h +++ b/python/port/genhdr/qstrdefs.in.h @@ -38,6 +38,7 @@ Q(right) Q(rt) Q(left) Q(lt) +Q(circle) Q(goto) Q(setpos) Q(setposition) diff --git a/python/port/mod/turtle/modturtle.cpp b/python/port/mod/turtle/modturtle.cpp index 393abd4fd..ed6b50599 100644 --- a/python/port/mod/turtle/modturtle.cpp +++ b/python/port/mod/turtle/modturtle.cpp @@ -44,6 +44,11 @@ mp_obj_t modturtle_left(mp_obj_t angle) { return mp_const_none; } +mp_obj_t modturtle_circle(mp_obj_t radius, mp_obj_t angle) { + sTurtle.circle(mp_obj_get_int(radius), mp_obj_get_float(angle)); + return mp_const_none; +} + mp_obj_t modturtle_goto(size_t n_args, const mp_obj_t *args) { mp_float_t x = 0; mp_float_t y = 0; diff --git a/python/port/mod/turtle/modturtle.h b/python/port/mod/turtle/modturtle.h index 3bd128296..b5f28bc01 100644 --- a/python/port/mod/turtle/modturtle.h +++ b/python/port/mod/turtle/modturtle.h @@ -9,6 +9,7 @@ mp_obj_t modturtle_forward(mp_obj_t px); mp_obj_t modturtle_backward(mp_obj_t px); mp_obj_t modturtle_right(mp_obj_t deg); mp_obj_t modturtle_left(mp_obj_t deg); +mp_obj_t modturtle_circle(mp_obj_t radius, mp_obj_t angle); mp_obj_t modturtle_goto(size_t n_args, const mp_obj_t *args); mp_obj_t modturtle_setheading(mp_obj_t deg); mp_obj_t modturtle_speed(mp_obj_t speed); diff --git a/python/port/mod/turtle/modturtle_table.c b/python/port/mod/turtle/modturtle_table.c index 6f90310f9..5d6259f58 100644 --- a/python/port/mod/turtle/modturtle_table.c +++ b/python/port/mod/turtle/modturtle_table.c @@ -6,6 +6,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(modturtle_forward_obj, modturtle_forward); STATIC MP_DEFINE_CONST_FUN_OBJ_1(modturtle_backward_obj, modturtle_backward); STATIC MP_DEFINE_CONST_FUN_OBJ_1(modturtle_right_obj, modturtle_right); STATIC MP_DEFINE_CONST_FUN_OBJ_1(modturtle_left_obj, modturtle_left); +STATIC MP_DEFINE_CONST_FUN_OBJ_2(modturtle_circle_obj, modturtle_circle); STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(modturtle_goto_obj, 1, 2, modturtle_goto); STATIC MP_DEFINE_CONST_FUN_OBJ_1(modturtle_setheading_obj, modturtle_setheading); STATIC MP_DEFINE_CONST_FUN_OBJ_1(modturtle_speed_obj, modturtle_speed); @@ -40,6 +41,7 @@ STATIC const mp_rom_map_elem_t modturtle_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_rt), (mp_obj_t)&modturtle_right_obj }, { MP_ROM_QSTR(MP_QSTR_left), (mp_obj_t)&modturtle_left_obj }, { MP_ROM_QSTR(MP_QSTR_lt), (mp_obj_t)&modturtle_left_obj }, + { MP_ROM_QSTR(MP_QSTR_circle), (mp_obj_t)&modturtle_circle_obj }, { MP_ROM_QSTR(MP_QSTR_goto), (mp_obj_t)&modturtle_goto_obj }, { MP_ROM_QSTR(MP_QSTR_setpos), (mp_obj_t)&modturtle_goto_obj }, { MP_ROM_QSTR(MP_QSTR_setposition), (mp_obj_t)&modturtle_goto_obj }, diff --git a/python/port/mod/turtle/turtle.cpp b/python/port/mod/turtle/turtle.cpp index 5496012f6..d6b6f3b96 100644 --- a/python/port/mod/turtle/turtle.cpp +++ b/python/port/mod/turtle/turtle.cpp @@ -36,8 +36,8 @@ void Turtle::reset() { draw(); } -void Turtle::forward(mp_float_t length) { - goTo( +bool Turtle::forward(mp_float_t length) { + return goTo( m_x + length * sin(m_heading), m_y + length * cos(m_heading) ); @@ -49,7 +49,30 @@ void Turtle::left(mp_float_t angle) { ); } -void Turtle::goTo(mp_float_t x, mp_float_t y) { +void Turtle::circle(mp_int_t radius, mp_float_t angle) { + mp_float_t oldHeading = heading(); + mp_float_t length = (angle*k_headingScale)*radius; + if (length > 1) { + int i = 1; + while(i <= length) { + mp_float_t progress = i / length; + if (m_speed > 0 && m_speed < k_maxSpeed) { + Ion::Display::waitForVBlank(); + } + // Move the turtle forward + if (forward(1)) { + // Keyboard interruption. Return now to let MicroPython process it. + return; + } + setHeadingPrivate(oldHeading+angle*progress); + i++; + } + forward(length-(i-1)); + setHeading(oldHeading+angle); + } +} + +bool Turtle::goTo(mp_float_t x, mp_float_t y) { mp_float_t oldx = m_x; mp_float_t oldy = m_y; mp_float_t length = sqrt((x - oldx) * (x - oldx) + (y - oldy) * (y - oldy)); @@ -67,7 +90,7 @@ void Turtle::goTo(mp_float_t x, mp_float_t y) { || draw()) { // Keyboard interruption. Return now to let MicroPython process it. - return; + return true; } } } @@ -76,6 +99,7 @@ void Turtle::goTo(mp_float_t x, mp_float_t y) { erase(); dot(x, y); draw(); + return false; } mp_float_t Turtle::heading() const { @@ -85,7 +109,7 @@ mp_float_t Turtle::heading() const { void Turtle::setHeading(mp_float_t angle) { micropython_port_vm_hook_loop(); - m_heading = k_invertedYAxisCoefficient * angle * k_headingScale + k_headingOffset; + setHeadingPrivate(angle); Ion::Display::waitForVBlank(); erase(); @@ -129,6 +153,10 @@ void Turtle::setVisible(bool visible) { // Private functions +void Turtle::setHeadingPrivate(mp_float_t angle) { + m_heading = k_invertedYAxisCoefficient * angle * k_headingScale + k_headingOffset; +} + KDPoint Turtle::position(mp_float_t x, mp_float_t y) const { return KDPoint(round(x + k_xOffset), round(k_invertedYAxisCoefficient * y + k_yOffset)); } diff --git a/python/port/mod/turtle/turtle.h b/python/port/mod/turtle/turtle.h index 1f6d043de..e8c383f9b 100644 --- a/python/port/mod/turtle/turtle.h +++ b/python/port/mod/turtle/turtle.h @@ -41,11 +41,12 @@ public: void reset(); - void forward(mp_float_t length); + bool forward(mp_float_t length); void backward(mp_float_t length) { forward(-length); } void right(mp_float_t angle) { left(-angle); } void left(mp_float_t angle); - void goTo(mp_float_t x, mp_float_t y); + void circle(mp_int_t radius, mp_float_t angle); + bool goTo(mp_float_t x, mp_float_t y); mp_float_t heading() const; void setHeading(mp_float_t angle); @@ -81,7 +82,7 @@ private: static constexpr KDColor k_defaultColor = KDColorBlack; static constexpr uint8_t k_defaultPenSize = 1; - + void setHeadingPrivate(mp_float_t angle); KDPoint position(mp_float_t x, mp_float_t y) const; KDPoint position() const { return position(m_x, m_y); }