diff --git a/ports/atmel-samd/boards/circuitbrains_deluxe_m4/mpconfigboard.mk b/ports/atmel-samd/boards/circuitbrains_deluxe_m4/mpconfigboard.mk index b470a2860e6a..49fc33c2da88 100755 --- a/ports/atmel-samd/boards/circuitbrains_deluxe_m4/mpconfigboard.mk +++ b/ports/atmel-samd/boards/circuitbrains_deluxe_m4/mpconfigboard.mk @@ -13,3 +13,4 @@ LONGINT_IMPL = MPZ CIRCUITPY_PS2IO = 1 CIRCUITPY_JPEGIO = 0 CIRCUITPY_SYNTHIO = 0 +CIRCUITPY_VECTORIO = 0 diff --git a/ports/atmel-samd/boards/datalore_ip_m4/mpconfigboard.mk b/ports/atmel-samd/boards/datalore_ip_m4/mpconfigboard.mk index 95123ae5b85d..55cb13b347f6 100644 --- a/ports/atmel-samd/boards/datalore_ip_m4/mpconfigboard.mk +++ b/ports/atmel-samd/boards/datalore_ip_m4/mpconfigboard.mk @@ -11,3 +11,4 @@ EXTERNAL_FLASH_DEVICES = "GD25Q16C, W25Q16JVxQ, W25Q16JVxM" LONGINT_IMPL = MPZ CIRCUITPY_SYNTHIO = 0 CIRCUITPY_JPEGIO = 0 +CIRCUITPY_VECTORIO = 0 diff --git a/ports/atmel-samd/boards/feather_m4_can/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m4_can/mpconfigboard.mk index 57c1ac918f96..70e7f8fd6cf2 100644 --- a/ports/atmel-samd/boards/feather_m4_can/mpconfigboard.mk +++ b/ports/atmel-samd/boards/feather_m4_can/mpconfigboard.mk @@ -16,6 +16,7 @@ CIRCUITPY_CANIO = 1 CIRCUITPY_SYNTHIO = 0 CIRCUITPY_GIFIO = 0 CIRCUITPY_JPEGIO = 0 +CIRCUITPY_VECTORIO = 0 CIRCUITPY_LTO_PARTITION = one diff --git a/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.mk index 16af70ef683f..022026b4ed63 100644 --- a/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.mk @@ -14,6 +14,7 @@ CIRCUITPY__EVE = 1 CIRCUITPY_FLOPPYIO = 0 CIRCUITPY_JPEGIO = 0 CIRCUITPY_SYNTHIO = 0 +CIRCUITPY_VECTORIO = 0 # We don't have room for the fonts for terminalio for certain languages, # so turn off terminalio, and if it's off and displayio is on, diff --git a/ports/atmel-samd/boards/hallowing_m4_express/mpconfigboard.mk b/ports/atmel-samd/boards/hallowing_m4_express/mpconfigboard.mk index 74f1d3e55993..1d61d1a31eaa 100644 --- a/ports/atmel-samd/boards/hallowing_m4_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/hallowing_m4_express/mpconfigboard.mk @@ -13,3 +13,4 @@ LONGINT_IMPL = MPZ CIRCUITPY_AESIO = 0 CIRCUITPY_JPEGIO = 0 CIRCUITPY_SYNTHIO = 0 +CIRCUITPY_VECTORIO = 0 diff --git a/ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.mk b/ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.mk index 4c11a905baa5..4baaa75aca64 100644 --- a/ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.mk @@ -13,5 +13,6 @@ LONGINT_IMPL = MPZ CIRCUITPY_FLOPPYIO = 0 CIRCUITPY_GIFIO = 0 CIRCUITPY_JPEGIO = 0 +CIRCUITPY_VECTORIO = 0 CIRCUITPY_BITBANG_APA102 = 1 diff --git a/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.mk b/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.mk index 0567918884ac..55a307ed4e30 100644 --- a/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.mk @@ -15,6 +15,7 @@ CIRCUITPY_CODEOP = 0 CIRCUITPY_FLOPPYIO = 0 CIRCUITPY_JPEGIO = 0 CIRCUITPY_SYNTHIO = 0 +CIRCUITPY_VECTORIO = 0 # We don't have room for the fonts for terminalio for certain languages, # so turn off terminalio, and if it's off and displayio is on, diff --git a/ports/atmel-samd/boards/mini_sam_m4/mpconfigboard.mk b/ports/atmel-samd/boards/mini_sam_m4/mpconfigboard.mk index 73c56fb5fbab..fe0c377c7196 100644 --- a/ports/atmel-samd/boards/mini_sam_m4/mpconfigboard.mk +++ b/ports/atmel-samd/boards/mini_sam_m4/mpconfigboard.mk @@ -13,6 +13,7 @@ LONGINT_IMPL = MPZ CIRCUITPY_FLOPPYIO = 0 CIRCUITPY_JPEGIO = 0 CIRCUITPY_SYNTHIO = 0 +CIRCUITPY_VECTORIO = 0 CIRCUITPY_BITBANG_APA102 = 1 diff --git a/ports/atmel-samd/boards/openbook_m4/mpconfigboard.mk b/ports/atmel-samd/boards/openbook_m4/mpconfigboard.mk index c6eaa6bd64d5..dc2104d4d349 100644 --- a/ports/atmel-samd/boards/openbook_m4/mpconfigboard.mk +++ b/ports/atmel-samd/boards/openbook_m4/mpconfigboard.mk @@ -13,3 +13,4 @@ LONGINT_IMPL = MPZ CIRCUITPY_KEYPAD = 1 CIRCUITPY_SYNTHIO = 0 CIRCUITPY_JPEGIO = 0 +CIRCUITPY_VECTORIO = 0 diff --git a/ports/atmel-samd/boards/pybadge/mpconfigboard.mk b/ports/atmel-samd/boards/pybadge/mpconfigboard.mk index 8005146114a4..a4afddf5e1da 100644 --- a/ports/atmel-samd/boards/pybadge/mpconfigboard.mk +++ b/ports/atmel-samd/boards/pybadge/mpconfigboard.mk @@ -19,5 +19,6 @@ CIRCUITPY_JPEGIO = 0 CIRCUITPY_KEYPAD = 1 CIRCUITPY_PARALLELDISPLAYBUS= 0 CIRCUITPY_STAGE = 1 +CIRCUITPY_VECTORIO = 0 FROZEN_MPY_DIRS += $(TOP)/frozen/circuitpython-stage/pybadge diff --git a/ports/atmel-samd/boards/pygamer/mpconfigboard.mk b/ports/atmel-samd/boards/pygamer/mpconfigboard.mk index 5149dda508fb..ccb1ccd5b4d1 100644 --- a/ports/atmel-samd/boards/pygamer/mpconfigboard.mk +++ b/ports/atmel-samd/boards/pygamer/mpconfigboard.mk @@ -19,5 +19,6 @@ CIRCUITPY_JPEGIO = 0 CIRCUITPY_KEYPAD = 1 CIRCUITPY_PARALLELDISPLAYBUS= 0 CIRCUITPY_STAGE = 1 +CIRCUITPY_VECTORIO = 0 FROZEN_MPY_DIRS += $(TOP)/frozen/circuitpython-stage/pygamer diff --git a/ports/atmel-samd/boards/seeeduino_wio_terminal/mpconfigboard.mk b/ports/atmel-samd/boards/seeeduino_wio_terminal/mpconfigboard.mk index dd8afd51f6e6..91c7ab1057d5 100644 --- a/ports/atmel-samd/boards/seeeduino_wio_terminal/mpconfigboard.mk +++ b/ports/atmel-samd/boards/seeeduino_wio_terminal/mpconfigboard.mk @@ -12,3 +12,4 @@ LONGINT_IMPL = MPZ CIRCUITPY_FLOPPYIO = 0 CIRCUITPY_FRAMEBUFFERIO = 0 CIRCUITPY_SYNTHIO = 0 +CIRCUITPY_VECTORIO = 0 diff --git a/ports/atmel-samd/boards/silicognition-m4-shim/mpconfigboard.mk b/ports/atmel-samd/boards/silicognition-m4-shim/mpconfigboard.mk index 7c576a0376bd..1de8cd3171e3 100644 --- a/ports/atmel-samd/boards/silicognition-m4-shim/mpconfigboard.mk +++ b/ports/atmel-samd/boards/silicognition-m4-shim/mpconfigboard.mk @@ -12,3 +12,4 @@ LONGINT_IMPL = MPZ CIRCUITPY_JPEGIO = 0 CIRCUITPY_SYNTHIO = 0 +CIRCUITPY_VECTORIO = 0 diff --git a/ports/atmel-samd/boards/uartlogger2/mpconfigboard.mk b/ports/atmel-samd/boards/uartlogger2/mpconfigboard.mk index 1181abd9640d..ee9a90f31ea9 100644 --- a/ports/atmel-samd/boards/uartlogger2/mpconfigboard.mk +++ b/ports/atmel-samd/boards/uartlogger2/mpconfigboard.mk @@ -11,3 +11,4 @@ EXTERNAL_FLASH_DEVICES = "W25Q32JVxQ" LONGINT_IMPL = MPZ CIRCUITPY_SYNTHIO = 0 CIRCUITPY_JPEGIO = 0 +CIRCUITPY_VECTORIO = 0 diff --git a/ports/espressif/boards/adafruit_qtpy_esp32c3/mpconfigboard.mk b/ports/espressif/boards/adafruit_qtpy_esp32c3/mpconfigboard.mk index 4063a6395226..86ee636511ee 100644 --- a/ports/espressif/boards/adafruit_qtpy_esp32c3/mpconfigboard.mk +++ b/ports/espressif/boards/adafruit_qtpy_esp32c3/mpconfigboard.mk @@ -13,3 +13,5 @@ CIRCUITPY_ESP_USB_SERIAL_JTAG = 1 # Not enough pins. CIRCUITPY_PARALLELDISPLAYBUS = 0 + +CIRCUITPY_VECTORIO = 0 diff --git a/ports/espressif/boards/ai_thinker_esp32-c3s/mpconfigboard.mk b/ports/espressif/boards/ai_thinker_esp32-c3s/mpconfigboard.mk index f907853f2382..89a2023c112d 100644 --- a/ports/espressif/boards/ai_thinker_esp32-c3s/mpconfigboard.mk +++ b/ports/espressif/boards/ai_thinker_esp32-c3s/mpconfigboard.mk @@ -10,3 +10,4 @@ CIRCUITPY_ESP_FLASH_SIZE = 4MB CIRCUITPY_LEGACY_4MB_FLASH_LAYOUT = 1 CIRCUITPY_ESP_USB_SERIAL_JTAG = 0 +CIRCUITPY_VECTORIO = 0 diff --git a/ports/espressif/boards/beetle-esp32-c3/mpconfigboard.mk b/ports/espressif/boards/beetle-esp32-c3/mpconfigboard.mk index a03e6c32eb2c..eba49afe5281 100644 --- a/ports/espressif/boards/beetle-esp32-c3/mpconfigboard.mk +++ b/ports/espressif/boards/beetle-esp32-c3/mpconfigboard.mk @@ -11,3 +11,5 @@ CIRCUITPY_ESP_FLASH_SIZE=4MB CIRCUITPY_LEGACY_4MB_FLASH_LAYOUT = 1 CIRCUITPY_ESP_USB_SERIAL_JTAG = 1 + +CIRCUITPY_VECTORIO = 0 diff --git a/ports/espressif/boards/lolin_c3_mini/mpconfigboard.mk b/ports/espressif/boards/lolin_c3_mini/mpconfigboard.mk index 36dc38883ff3..52d09dbc6f1f 100644 --- a/ports/espressif/boards/lolin_c3_mini/mpconfigboard.mk +++ b/ports/espressif/boards/lolin_c3_mini/mpconfigboard.mk @@ -10,3 +10,5 @@ CIRCUITPY_ESP_FLASH_SIZE=4MB CIRCUITPY_LEGACY_4MB_FLASH_LAYOUT = 1 CIRCUITPY_ESP_USB_SERIAL_JTAG = 1 + +CIRCUITPY_VECTORIO = 0 diff --git a/ports/espressif/boards/makergo_esp32c3_supermini/mpconfigboard.mk b/ports/espressif/boards/makergo_esp32c3_supermini/mpconfigboard.mk index 37c27203af31..9090f0aa15d6 100644 --- a/ports/espressif/boards/makergo_esp32c3_supermini/mpconfigboard.mk +++ b/ports/espressif/boards/makergo_esp32c3_supermini/mpconfigboard.mk @@ -10,3 +10,5 @@ CIRCUITPY_ESP_FLASH_SIZE=4MB CIRCUITPY_LEGACY_4MB_FLASH_LAYOUT = 1 CIRCUITPY_ESP_USB_SERIAL_JTAG = 1 + +CIRCUITPY_VECTORIO = 0 diff --git a/ports/espressif/boards/microdev_micro_c3/mpconfigboard.mk b/ports/espressif/boards/microdev_micro_c3/mpconfigboard.mk index b2ea6005db53..7cc75f002504 100644 --- a/ports/espressif/boards/microdev_micro_c3/mpconfigboard.mk +++ b/ports/espressif/boards/microdev_micro_c3/mpconfigboard.mk @@ -10,3 +10,5 @@ CIRCUITPY_ESP_FLASH_SIZE = 4MB CIRCUITPY_LEGACY_4MB_FLASH_LAYOUT = 1 CIRCUITPY_ESP_USB_SERIAL_JTAG = 1 + +CIRCUITPY_VECTORIO = 0 diff --git a/ports/raspberrypi/boards/wiznet_w5500_evb_pico/mpconfigboard.mk b/ports/raspberrypi/boards/wiznet_w5500_evb_pico/mpconfigboard.mk index 127cdaba380e..1ffaffc89538 100644 --- a/ports/raspberrypi/boards/wiznet_w5500_evb_pico/mpconfigboard.mk +++ b/ports/raspberrypi/boards/wiznet_w5500_evb_pico/mpconfigboard.mk @@ -10,3 +10,4 @@ EXTERNAL_FLASH_DEVICES = "W25Q16JVxQ" CIRCUITPY__EVE = 1 CIRCUITPY_SSL = 1 +CIRCUITPY_VECTORIO = 0 diff --git a/ports/stm/boards/meowbit_v121/mpconfigboard.mk b/ports/stm/boards/meowbit_v121/mpconfigboard.mk index 52c191b5b2ef..a1eef07565ff 100644 --- a/ports/stm/boards/meowbit_v121/mpconfigboard.mk +++ b/ports/stm/boards/meowbit_v121/mpconfigboard.mk @@ -30,6 +30,7 @@ CIRCUITPY_EPAPERDISPLAY = 0 CIRCUITPY_KEYPAD_DEMUX = 0 CIRCUITPY_SHARPDISPLAY = 0 CIRCUITPY_ULAB = 0 +CIRCUITPY_VECTORIO = 0 CIRCUITPY_ZLIB = 0 CIRCUITPY_STAGE = 1 diff --git a/shared-bindings/vectorio/__init__.c b/shared-bindings/vectorio/__init__.c index 7e9473eefdcb..ceb366683e3a 100644 --- a/shared-bindings/vectorio/__init__.c +++ b/shared-bindings/vectorio/__init__.c @@ -9,9 +9,11 @@ #include "py/obj.h" #include "py/runtime.h" + #include "shared-bindings/vectorio/Circle.h" #include "shared-bindings/vectorio/Polygon.h" #include "shared-bindings/vectorio/Rectangle.h" +#include "shared-bindings/vectorio/__init__.h" //| """Lightweight 2D shapes for displays //| @@ -36,9 +38,600 @@ //| group.append(polygon) //| //| """ +//| + + +//| def circle_rectangle_intersects( +//| cx: int, cy: int, cr: int, rx: int, ry: int, rw: int, rh: int +//| ) -> bool: +//| """Checks for intersection between a cricle and a rectangle. +//| +//| :param int cx: Circle center x coordinate +//| :param int cy: Circle center y coordinate +//| :param int cr: Circle radius +//| :param int rx: Rectangle x coordinate +//| :param int ry: Rectangle y coordinate +//| :param int rw: Rectangle width +//| :param int rh: Rectangle height""" +//| ... +//| +static mp_obj_t vectorio_circle_rectangle_intersects(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum {ARG_cx, ARG_cy, ARG_cr, ARG_rx, ARG_ry, ARG_rw, ARG_rh}; + + static const mp_arg_t allowed_args[] = { + {MP_QSTR_cx, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_cy, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_cr, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_rx, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_ry, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_rw, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_rh, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + int16_t cx = args[ARG_cx].u_int; + int16_t cy = args[ARG_cy].u_int; + int16_t cr = args[ARG_cr].u_int; + int16_t rx = args[ARG_rx].u_int; + int16_t ry = args[ARG_ry].u_int; + int16_t rw = args[ARG_rw].u_int; + int16_t rh = args[ARG_rh].u_int; + + bool result = common_hal_vectorio_circle_rectangle_intersects(cx, cy, cr, rx, ry, rw, rh); + if (result) { + return mp_const_true; + } else { + return mp_const_false; + } +} +MP_DEFINE_CONST_FUN_OBJ_KW(vectorio_circle_rectangle_intersects_obj, 0, vectorio_circle_rectangle_intersects); + + +//| def rectangle_rectangle_intersects( +//| r1x: int, r1y: int, r1w: int, r1h: int, r2x: int, r2y: int, r2w: int, r2h: int +//| ) -> bool: +//| """Checks for intersection between a two rectangles. +//| +//| :param int r1x: First Rectangle x coordinate +//| :param int r1y: First Rectangle y coordinate +//| :param int r1w: First Rectangle width +//| :param int r1h: First Rectangle height +//| :param int r2x: Second Rectangle x coordinate +//| :param int r2y: Second Rectangle y coordinate +//| :param int r2w: Second Rectangle width +//| :param int r2h: Second Rectangle height""" +//| ... +//| +static mp_obj_t vectorio_rectangle_rectangle_intersects(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum {ARG_r1x, ARG_r1y, ARG_r1w, ARG_r1h, ARG_r2x, ARG_r2y, ARG_r2w, ARG_r2h}; + + static const mp_arg_t allowed_args[] = { + {MP_QSTR_r1x, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_r1y, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_r1w, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_r1h, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_r2x, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_r2y, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_r2w, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_r2h, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + int16_t r1x = args[ARG_r1x].u_int; + int16_t r1y = args[ARG_r1y].u_int; + int16_t r1w = args[ARG_r1w].u_int; + int16_t r1h = args[ARG_r1h].u_int; + + int16_t r2x = args[ARG_r2x].u_int; + int16_t r2y = args[ARG_r2y].u_int; + int16_t r2w = args[ARG_r2w].u_int; + int16_t r2h = args[ARG_r2h].u_int; + + + bool result = common_hal_vectorio_rectangle_rectangle_intersects(r1x, r1y, r1w, r1h, r2x, r2y, r2w, r2h); + if (result) { + return mp_const_true; + } else { + return mp_const_false; + } +} +MP_DEFINE_CONST_FUN_OBJ_KW(vectorio_rectangle_rectangle_intersects_obj, 0, vectorio_rectangle_rectangle_intersects); + +//| def circle_circle_intersects( +//| c1x: int, c1y: int, c1r: int, c2x: int, c2y: int, c2r: int +//| ) -> bool: +//| """Checks for intersection between two circles. +//| +//| :param int c1x: First Circle center x coordinate +//| :param int c1y: First Circle center y coordinate +//| :param int c1r: First Circle radius +//| :param int c2x: Second Circle center x coordinate +//| :param int c2y: Second Circle center y coordinate +//| :param int c2r: Second Circle radius""" +//| ... +//| +static mp_obj_t vectorio_circle_circle_intersects(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum {ARG_c1x, ARG_c1y, ARG_c1r, ARG_c2x, ARG_c2y, ARG_c2r}; + + static const mp_arg_t allowed_args[] = { + {MP_QSTR_c1x, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_c1y, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_c1r, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_c2x, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_c2y, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_c2r, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + int16_t c1x = args[ARG_c1x].u_int; + int16_t c1y = args[ARG_c1y].u_int; + int16_t c1r = args[ARG_c1r].u_int; + int16_t c2x = args[ARG_c2x].u_int; + int16_t c2y = args[ARG_c2y].u_int; + int16_t c2r = args[ARG_c2r].u_int; + + bool result = common_hal_vectorio_circle_circle_intersects(c1x, c1y, c1r, c2x, c2y, c2r); + if (result) { + return mp_const_true; + } else { + return mp_const_false; + } +} +MP_DEFINE_CONST_FUN_OBJ_KW(vectorio_circle_circle_intersects_obj, 0, vectorio_circle_circle_intersects); + +//| def circle_contains_point(cx: int, cy: int, cr: int, px: int, py: int) -> bool: +//| """Checks whether a circle contains the given point +//| +//| :param int cx: Circle center x coordinate +//| :param int cy: Circle center y coordinate +//| :param int cr: Circle radius +//| :param int px: Point x coordinate +//| :param int py: Point y coordinate""" +//| ... +//| +static mp_obj_t vectorio_circle_contains_point(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum {ARG_cx, ARG_cy, ARG_cr, ARG_px, ARG_py}; + + static const mp_arg_t allowed_args[] = { + {MP_QSTR_cx, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_cy, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_cr, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_px, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_py, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + int16_t cx = args[ARG_cx].u_int; + int16_t cy = args[ARG_cy].u_int; + int16_t cr = args[ARG_cr].u_int; + int16_t px = args[ARG_px].u_int; + int16_t py = args[ARG_py].u_int; + + bool result = common_hal_vectorio_circle_contains_point(cx, cy, cr, px, py); + if (result) { + return mp_const_true; + } else { + return mp_const_false; + } +} +MP_DEFINE_CONST_FUN_OBJ_KW(vectorio_circle_contains_point_obj, 0, vectorio_circle_contains_point); + +//| def rectangle_contains_point(rx: int, ry: int, rw: int, rh: int, px: int, py: int) -> bool: +//| """Checks whether a rectangle contains the given point +//| +//| :param int rx: Rectangle x coordinate +//| :param int ry: Rectangle y coordinate +//| :param int rw: Rectangle width +//| :param int rh: Rectangle height +//| :param int px: Point x coordinate +//| :param int py: Point y coordinate""" +//| ... +//| +static mp_obj_t vectorio_rectangle_contains_point(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum {ARG_rx, ARG_ry, ARG_rw, ARG_rh, ARG_px, ARG_py}; + + static const mp_arg_t allowed_args[] = { + {MP_QSTR_rx, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_ry, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_rw, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_rh, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_px, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_py, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + int16_t rx = args[ARG_rx].u_int; + int16_t ry = args[ARG_ry].u_int; + int16_t rw = args[ARG_rw].u_int; + int16_t rh = args[ARG_rh].u_int; + int16_t px = args[ARG_px].u_int; + int16_t py = args[ARG_py].u_int; + + bool result = common_hal_vectorio_rectangle_contains_point(rx, ry, rw, rh, px, py); + if (result) { + return mp_const_true; + } else { + return mp_const_false; + } +} +MP_DEFINE_CONST_FUN_OBJ_KW(vectorio_rectangle_contains_point_obj, 0, vectorio_rectangle_contains_point); + + +//| def line_contains_point(x1: int, y1: int, x2: int, y2: int, px: int, py: int) -> bool: +//| """Checks whether a line contains the given point +//| +//| :param int x1: Line x1 coordinate +//| :param int y1: Line y1 coordinate +//| :param int x2: Line x2 coordinate +//| :param int y2: Line y2 coordinate +//| :param int px: Point x coordinate +//| :param int py: Point y coordinate +//| :param float padding: Extra padding outside of the line to consider as positive intersection +//| """ +//| ... +//| +static mp_obj_t vectorio_line_contains_point(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum {ARG_x1, ARG_y1, ARG_x2, ARG_y2, ARG_px, ARG_py, ARG_padding}; + + static const mp_arg_t allowed_args[] = { + {MP_QSTR_x1, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_y1, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_x2, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_y2, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_px, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_py, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_padding, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, // None convert to 0.0 + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + int16_t x1 = args[ARG_x1].u_int; + int16_t y1 = args[ARG_y1].u_int; + int16_t x2 = args[ARG_x2].u_int; + int16_t y2 = args[ARG_y2].u_int; + int16_t px = args[ARG_px].u_int; + int16_t py = args[ARG_py].u_int; + + // Use default padding if None was passed + mp_float_t padding = 0.0; + if (args[ARG_padding].u_obj != mp_const_none) { + padding = mp_obj_get_float(args[ARG_padding].u_obj); + } + + bool result = common_hal_vectorio_line_contains_point(x1, y1, x2, y2, px, py, padding); + if (result) { + return mp_const_true; + } else { + return mp_const_false; + } +} +MP_DEFINE_CONST_FUN_OBJ_KW(vectorio_line_contains_point_obj, 0, vectorio_line_contains_point); + + +//| def line_circle_intersects( +//| x1: int, +//| y1: int, +//| x2: int, +//| y2: int, +// cx: int, cy: int, cr: int +//| ) -> bool: +//| """Checks whether a line intersects with a circle +//| +//| :param int x1: Line x1 coordinate +//| :param int y1: Line y1 coordinate +//| :param int x2: Line x2 coordinate +//| :param int y2: Line y2 coordinate +//| :param int cx: Circle center x coordinate +//| :param int cy: Circle center y coordinate +//| :param int cr: Circle radius +//| :param float padding: Extra padding outside of the line to consider as positive intersection +//| """ +//| ... +//| +static mp_obj_t vectorio_line_circle_intersects(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum {ARG_x1, ARG_y1, ARG_x2, ARG_y2, ARG_cx, ARG_cy, ARG_cr, ARG_padding}; + + static const mp_arg_t allowed_args[] = { + {MP_QSTR_x1, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_y1, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_x2, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_y2, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_cx, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_cy, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_cr, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_padding, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, // None convert to 0.0 + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + int16_t x1 = args[ARG_x1].u_int; + int16_t y1 = args[ARG_y1].u_int; + int16_t x2 = args[ARG_x2].u_int; + int16_t y2 = args[ARG_y2].u_int; + int16_t cx = args[ARG_cx].u_int; + int16_t cy = args[ARG_cy].u_int; + int16_t cr = args[ARG_cr].u_int; + + // Use default padding if None was passed + mp_float_t padding = 0.0; + if (args[ARG_padding].u_obj != mp_const_none) { + padding = mp_obj_get_float(args[ARG_padding].u_obj); + } + + bool result = common_hal_vectorio_line_circle_intersects(x1, y1, x2, y2, cx, cy, cr, padding); + + if (result) { + return mp_const_true; + } else { + return mp_const_false; + } +} +MP_DEFINE_CONST_FUN_OBJ_KW(vectorio_line_circle_intersects_obj, 0, vectorio_line_circle_intersects); + + +//| def polygon_circle_intersects( +//| points: List[Tuple[int, int]], +//| polygon_x: int, +//| polygon_y: int, +//| cx: int, +//| cy: int, +//| cr: int, +//| padding: float, +//| ) -> bool: +//| """Checks for intersection between a polygon and a cricle. +//| +//| :param List[Tuple[int,int]] points: Vertices for the polygon +//| :param int polygon_x: Polygon x coordinate. All other polygon points are relative to this +//| :param int polygon_y: Polygon y coordinate. All other polygon points are relative to this +//| :param int cx: Circle center x coordinate +//| :param int cy: Circle center y coordinate +//| :param int cr: Circle radius +//| :param float padding: Extra padding outside of the line to consider as positive intersection +//| """ +//| ... +//| +static mp_obj_t vectorio_polygon_circle_intersects(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum {ARG_points_list, ARG_polygon_x, ARG_polygon_y, ARG_cx, ARG_cy, ARG_cr, ARG_padding}; + + static const mp_arg_t allowed_args[] = { + {MP_QSTR_points, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_polygon_x, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_polygon_y, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_cx, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_cy, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_cr, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_padding, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, // None convert to 0.0 + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_obj_t points_list = mp_arg_validate_type(args[ARG_points_list].u_obj, &mp_type_list, MP_QSTR_points); + + int16_t polygon_x = args[ARG_polygon_x].u_int; + int16_t polygon_y = args[ARG_polygon_y].u_int; + + int16_t cx = args[ARG_cx].u_int; + int16_t cy = args[ARG_cy].u_int; + int16_t cr = args[ARG_cr].u_int; + + // Use default padding if None was passed + mp_float_t padding = 0.0; + if (args[ARG_padding].u_obj != mp_const_none) { + padding = mp_obj_get_float(args[ARG_padding].u_obj); + } + + bool result = common_hal_vectorio_polygon_circle_intersects( + points_list, polygon_x, polygon_y, + cx, cy, cr, padding + ); + + if (result) { + return mp_const_true; + } else { + return mp_const_false; + } +} +MP_DEFINE_CONST_FUN_OBJ_KW(vectorio_polygon_circle_intersects_obj, 0, vectorio_polygon_circle_intersects); + + +//| def line_line_intersects( +//| x1: int, +//| y1: int, +//| x2: int, +//| y2: int, +//| x3: int, +//| y3: int, +//| x4: int, +//| y4: int, +//| ) -> bool: +//| """Checks whether a line intersects with another line +//| +//| :param int x1: Line x1 coordinate +//| :param int y1: Line y1 coordinate +//| :param int x2: Line x2 coordinate +//| :param int y2: Line y2 coordinate +//| :param int x3: Other Line x3 coordinate +//| :param int y3: Other Line y3 coordinate +//| :param int x4: Other Line x4 coordinate +//| :param int y4: Other Line y4 coordinate""" +//| ... +//| +static mp_obj_t vectorio_line_line_intersects(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum {ARG_x1, ARG_y1, ARG_x2, ARG_y2, ARG_x3, ARG_y3, ARG_x4, ARG_y4 }; + + static const mp_arg_t allowed_args[] = { + {MP_QSTR_x1, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_y1, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_x2, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_y2, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_x3, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_y3, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_x4, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_y4, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + int16_t x1 = args[ARG_x1].u_int; + int16_t y1 = args[ARG_y1].u_int; + int16_t x2 = args[ARG_x2].u_int; + int16_t y2 = args[ARG_y2].u_int; + int16_t x3 = args[ARG_x3].u_int; + int16_t y3 = args[ARG_y3].u_int; + int16_t x4 = args[ARG_x4].u_int; + int16_t y4 = args[ARG_y4].u_int; + + bool result = common_hal_vectorio_line_line_intersects(x1, y1, x2, y2, x3, y3, x4, y4); + + if (result) { + return mp_const_true; + } else { + return mp_const_false; + } +} +MP_DEFINE_CONST_FUN_OBJ_KW(vectorio_line_line_intersects_obj, 0, vectorio_line_line_intersects); + + +//| def line_rectangle_intersects( +//| x1: int, y1: int, x2: int, y2: int, rx: int, ry: int, rw: int, rh: int +//| ) -> bool: +//| """Checks whether a line intersects with another line +//| +//| :param int x1: Line x1 coordinate +//| :param int y1: Line y1 coordinate +//| :param int x2: Line x2 coordinate +//| :param int y2: Line y2 coordinate +//| :param int rx: Rectangle x coordinate +//| :param int ry: Rectangle y coordinate +//| :param int rw: Rectangle width +//| :param int rh: Rectangle height""" +//| ... +//| +static mp_obj_t vectorio_line_rectangle_intersects(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum {ARG_x1, ARG_y1, ARG_x2, ARG_y2, ARG_rx, ARG_ry, ARG_rw, ARG_rh }; + + static const mp_arg_t allowed_args[] = { + {MP_QSTR_x1, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_y1, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_x2, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_y2, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_rx, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_ry, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_rw, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_rh, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + int16_t x1 = args[ARG_x1].u_int; + int16_t y1 = args[ARG_y1].u_int; + int16_t x2 = args[ARG_x2].u_int; + int16_t y2 = args[ARG_y2].u_int; + int16_t rx = args[ARG_rx].u_int; + int16_t ry = args[ARG_ry].u_int; + int16_t rw = args[ARG_rw].u_int; + int16_t rh = args[ARG_rh].u_int; + + bool result = common_hal_vectorio_line_rectangle_intersects(x1, y1, x2, y2, rx, ry, rw, rh); + + if (result) { + return mp_const_true; + } else { + return mp_const_false; + } +} +MP_DEFINE_CONST_FUN_OBJ_KW(vectorio_line_rectangle_intersects_obj, 0, vectorio_line_rectangle_intersects); + + +//| def polygon_rectangle_intersects( +//| points: List[Tuple[int, int]], +//| polygon_x: int, +//| polygon_y: int, +//| rx: int, +//| ry: int, +//| rw: int, +//| rh: int, +//| ) -> bool: +//| """Checks for intersection between a polygon and a cricle. +//| +//| :param List[Tuple[int,int]] points: Vertices for the polygon +//| :param int polygon_x: Polygon x coordinate. All other polygon points are relative to this +//| :param int polygon_y: Polygon y coordinate. All other polygon points are relative to this +//| :param int rx: Rectangle x coordinate +//| :param int ry: Rectangle y coordinate +//| :param int rw: Rectangle width +//| :param int rh: Rectangle height""" +//| ... +//| +static mp_obj_t vectorio_polygon_rectangle_intersects(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum {ARG_points_list, ARG_polygon_x, ARG_polygon_y, ARG_rx, ARG_ry, ARG_rw, ARG_rh}; + + static const mp_arg_t allowed_args[] = { + {MP_QSTR_points, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_polygon_x, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_polygon_y, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_rx, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_ry, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_rw, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_rh, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_padding, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, // None convert to 0.0 + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_obj_t points_list = mp_arg_validate_type(args[ARG_points_list].u_obj, &mp_type_list, MP_QSTR_points); + + int16_t polygon_x = args[ARG_polygon_x].u_int; + int16_t polygon_y = args[ARG_polygon_y].u_int; + + int16_t rx = args[ARG_rx].u_int; + int16_t ry = args[ARG_ry].u_int; + int16_t rw = args[ARG_rw].u_int; + int16_t rh = args[ARG_rh].u_int; + + bool result = common_hal_vectorio_polygon_rectangle_intersects( + points_list, polygon_x, polygon_y, + rx, ry, rw, rh + ); + + if (result) { + return mp_const_true; + } else { + return mp_const_false; + } +} +MP_DEFINE_CONST_FUN_OBJ_KW(vectorio_polygon_rectangle_intersects_obj, 0, vectorio_polygon_rectangle_intersects); + static const mp_rom_map_elem_t vectorio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_vectorio) }, + { MP_ROM_QSTR(MP_QSTR_circle_rectangle_intersects), MP_ROM_PTR(&vectorio_circle_rectangle_intersects_obj) }, + { MP_ROM_QSTR(MP_QSTR_polygon_circle_intersects), MP_ROM_PTR(&vectorio_polygon_circle_intersects_obj) }, + { MP_ROM_QSTR(MP_QSTR_circle_circle_intersects), MP_ROM_PTR(&vectorio_circle_circle_intersects_obj) }, + { MP_ROM_QSTR(MP_QSTR_line_circle_intersects), MP_ROM_PTR(&vectorio_line_circle_intersects_obj) }, + { MP_ROM_QSTR(MP_QSTR_line_line_intersects), MP_ROM_PTR(&vectorio_line_line_intersects_obj) }, + { MP_ROM_QSTR(MP_QSTR_line_rectangle_intersects), MP_ROM_PTR(&vectorio_line_rectangle_intersects_obj) }, + { MP_ROM_QSTR(MP_QSTR_polygon_rectangle_intersects), MP_ROM_PTR(&vectorio_polygon_rectangle_intersects_obj) }, + { MP_ROM_QSTR(MP_QSTR_circle_contains_point), MP_ROM_PTR(&vectorio_circle_contains_point_obj) }, + { MP_ROM_QSTR(MP_QSTR_rectangle_contains_point), MP_ROM_PTR(&vectorio_rectangle_contains_point_obj) }, + { MP_ROM_QSTR(MP_QSTR_line_contains_point), MP_ROM_PTR(&vectorio_line_contains_point_obj) }, + { MP_ROM_QSTR(MP_QSTR_rectangle_rectangle_intersects), MP_ROM_PTR(&vectorio_rectangle_rectangle_intersects_obj) }, { MP_ROM_QSTR(MP_QSTR_Circle), MP_ROM_PTR(&vectorio_circle_type) }, { MP_ROM_QSTR(MP_QSTR_Polygon), MP_ROM_PTR(&vectorio_polygon_type) }, { MP_ROM_QSTR(MP_QSTR_Rectangle), MP_ROM_PTR(&vectorio_rectangle_type) }, diff --git a/shared-bindings/vectorio/__init__.h b/shared-bindings/vectorio/__init__.h index c982f63815b4..beaba0cd3e5c 100644 --- a/shared-bindings/vectorio/__init__.h +++ b/shared-bindings/vectorio/__init__.h @@ -44,3 +44,49 @@ typedef struct _vectorio_draw_protocol_t { // Implementation functions for the draw protocol vectorio_draw_protocol_impl_t *draw_protocol_impl; } vectorio_draw_protocol_t; + +bool common_hal_vectorio_circle_rectangle_intersects( + int16_t cx, int16_t cy, int16_t cr, + int16_t rx, int16_t ry, int16_t rw, int16_t rh); + +bool common_hal_vectorio_rectangle_rectangle_intersects( + int16_t r1x, int16_t r1y, int16_t r1w, int16_t r1h, + int16_t r2x, int16_t r2y, int16_t r2w, int16_t r2h); + +bool common_hal_vectorio_circle_circle_intersects( + int16_t c1x, int16_t c1y, int16_t c1r, + int16_t c2x, int16_t c2y, int16_t c2r); + +bool common_hal_vectorio_circle_contains_point( + int16_t cx, int16_t cy, int16_t cr, + int16_t px, int16_t py); + +bool common_hal_vectorio_rectangle_contains_point( + int16_t rx, int16_t ry, int16_t rw, int16_t rh, + int16_t px, int16_t py); + +bool common_hal_vectorio_line_contains_point( + int16_t x1, int16_t y1, int16_t x2, int16_t y2, + int16_t px, int16_t py, mp_float_t padding); + +bool common_hal_vectorio_line_circle_intersects( + int16_t x1, int16_t y1, int16_t x2, int16_t y2, + int16_t cx, int16_t cy, int16_t cr, mp_float_t padding); + +bool common_hal_vectorio_polygon_circle_intersects( + mp_obj_t points_list, int16_t polygon_x, int16_t polygon_y, + int16_t cx, int16_t cy, int16_t cr, mp_float_t padding); + +bool common_hal_vectorio_line_line_intersects( + int16_t x1, int16_t y1, int16_t x2, int16_t y2, + int16_t x3, int16_t y3, int16_t x4, int16_t y4 + ); + +bool common_hal_vectorio_line_rectangle_intersects( + int16_t x1, int16_t y1, int16_t x2, int16_t y2, + int16_t rx, int16_t ry, int16_t rw, int16_t rh + ); + +bool common_hal_vectorio_polygon_rectangle_intersects( + mp_obj_t points_list, int16_t polygon_x, int16_t polygon_y, + int16_t rx, int16_t ry, int16_t rw, int16_t rh); diff --git a/shared-module/vectorio/__init__.c b/shared-module/vectorio/__init__.c index 0c16efad6eda..cb4dac5dec0e 100644 --- a/shared-module/vectorio/__init__.c +++ b/shared-module/vectorio/__init__.c @@ -5,3 +5,307 @@ // SPDX-License-Identifier: MIT // Don't need anything in here yet + +#include "shared-bindings/vectorio/__init__.h" +#include "shared-module/vectorio/__init__.h" + +#include "py/runtime.h" +#include "stdlib.h" +#include + +bool common_hal_vectorio_circle_rectangle_intersects( + int16_t cx, int16_t cy, int16_t cr, + int16_t rx, int16_t ry, int16_t rw, int16_t rh) { + + mp_int_t rect_left = rx; + mp_int_t rect_right = rect_left + rw; + mp_int_t rect_top = ry; + mp_int_t rect_bottom = rect_top + rh; + + mp_int_t test_x = cx; + mp_int_t test_y = cy; + + if (cx < rect_left) { + test_x = rect_left; + } else if (cx > rect_right) { + test_x = rect_right; + } + + if (cy < rect_top) { + test_y = rect_top; + } else if (cy > rect_bottom) { + test_y = rect_bottom; + } + + mp_int_t dist_x = cx - test_x; + mp_int_t dist_y = cy - test_y; + mp_int_t dist = (dist_x * dist_x) + (dist_y * dist_y); + + return dist <= cr * cr; +} + +bool common_hal_vectorio_circle_circle_intersects( + int16_t c1x, int16_t c1y, int16_t c1r, + int16_t c2x, int16_t c2y, int16_t c2r + ) { + + mp_int_t dist_x = c1x - c2x; + mp_int_t dist_y = c1y - c2y; + + mp_int_t dist = (dist_x * dist_x) + (dist_y * dist_y); + + return dist <= (c1r + c2r) * (c1r + c2r); + +} + +bool common_hal_vectorio_circle_contains_point( + int16_t cx, int16_t cy, int16_t cr, + int16_t px, int16_t py + ) { + + mp_int_t dist_x = px - cx; + mp_int_t dist_y = py - cy; + + mp_int_t dist_sq = (dist_x * dist_x) + (dist_y * dist_y); + + return dist_sq <= cr * cr; +} + +bool common_hal_vectorio_rectangle_contains_point( + int16_t rx, int16_t ry, int16_t rw, int16_t rh, + int16_t px, int16_t py + ) { + + if (rx > px) { + return false; + } + if (px > rx + rw) { + return false; + } + if (ry > py) { + return false; + } + if (py > ry + rh) { + return false; + } + return true; +} + +float measure_distance(float x1, float y1, float x2, float y2) { + float dist_x = x1 - x2; + float dist_y = y1 - y2; + return sqrtf((dist_x * dist_x) + (dist_y * dist_y)); +} + +bool common_hal_vectorio_line_contains_point( + int16_t x1, int16_t y1, int16_t x2, int16_t y2, + int16_t px, int16_t py, mp_float_t padding + ) { + + float line_length = measure_distance(x1, y1, x2, y2); + float d1 = measure_distance(x1, y1, px, py); + float d2 = measure_distance(x2, y2, px, py); + + if (d1 + d2 >= line_length - padding && d1 + d2 <= line_length + padding) { + return true; + } + return false; + +} + +bool common_hal_vectorio_line_circle_intersects( + int16_t x1, int16_t y1, int16_t x2, int16_t y2, + int16_t cx, int16_t cy, int16_t cr, mp_float_t padding + ) { + if (common_hal_vectorio_circle_contains_point(cx, cy, cr, x1, y1)) { + return true; + } + if (common_hal_vectorio_circle_contains_point(cx, cy, cr, x2, y2)) { + return true; + } + float line_length = measure_distance(x1, y1, x2, y2); + + float dot = (((cx - x1) * (x2 - x1)) + ((cy - y1) * (y2 - y1))) / pow(line_length, 2); + + float closestX = x1 + (dot * (x2 - x1)); + float closestY = y1 + (dot * (y2 - y1)); + + if (!common_hal_vectorio_line_contains_point(x1, y1, x2, y2, closestX, closestY, padding)) { + return false; + } + float distance = measure_distance(closestX, closestY, cx, cy); + if (distance <= cr) { + return true; + } else { + return false; + } + +} + +bool common_hal_vectorio_rectangle_rectangle_intersects( + int16_t r1x, int16_t r1y, int16_t r1w, int16_t r1h, + int16_t r2x, int16_t r2y, int16_t r2w, int16_t r2h) { + + + mp_int_t r1_left = r1x; + mp_int_t r1_right = r1_left + r1w; + mp_int_t r1_top = r1y; + mp_int_t r1_bottom = r1_top + r1h; + + mp_int_t r2_left = r2x; + mp_int_t r2_right = r2_left + r2w; + mp_int_t r2_top = r2y; + mp_int_t r2_bottom = r2_top + r2h; + + return r1_left < r2_right && r1_right > r2_left && + r1_top < r2_bottom && r1_bottom > r2_top; +} + +bool common_hal_vectorio_polygon_circle_intersects( + mp_obj_t points_list, int16_t polygon_x, int16_t polygon_y, int16_t cx, int16_t cy, int16_t cr, mp_float_t padding + ) { + size_t len = 0; + mp_obj_t *points_list_items; + mp_obj_list_get(points_list, &len, &points_list_items); + bool polygon_contains_point = false; + for (uint16_t i = 0; i < len; i++) { + size_t cur_tuple_len = 0; + mp_obj_t *cur_point_tuple; + mp_arg_validate_type(points_list_items[i], &mp_type_tuple, MP_QSTR_point); + mp_obj_tuple_get(points_list_items[i], &cur_tuple_len, &cur_point_tuple); + + mp_int_t cur_x = mp_arg_validate_type_int(cur_point_tuple[0], MP_QSTR_x) + polygon_x; + mp_int_t cur_y = mp_arg_validate_type_int(cur_point_tuple[1], MP_QSTR_y) + polygon_y; + + size_t next_tuple_len = 0; + mp_obj_t *next_point_tuple; + int next_index = (i + 1) % len; + mp_arg_validate_type(points_list_items[next_index], &mp_type_tuple, MP_QSTR_point); + mp_obj_tuple_get(points_list_items[next_index], &next_tuple_len, &next_point_tuple); + + mp_int_t next_x = mp_arg_validate_type_int(next_point_tuple[0], MP_QSTR_x) + polygon_x; + mp_int_t next_y = mp_arg_validate_type_int(next_point_tuple[1], MP_QSTR_y) + polygon_y; + + // mp_printf(&mp_plat_print, "%d,%d - %d,%d \n", cur_x, cur_y, next_x, next_y); + + if (common_hal_vectorio_line_circle_intersects( + cur_x, cur_y, next_x, next_y, + cx, cy, cr, padding + )) { + return true; + } + + if (((cur_y >= cy && cy > next_y) || (cur_y < cy && cy <= next_y)) && + (cx < (next_x - cur_x) * (cy - cur_y) / (next_y - cur_y) + cur_x)) { + + polygon_contains_point = !polygon_contains_point; + } + + } + if (polygon_contains_point == true) { + return true; + } + return false; +} + + + +bool common_hal_vectorio_line_line_intersects( + int16_t x1, int16_t y1, int16_t x2, int16_t y2, + int16_t x3, int16_t y3, int16_t x4, int16_t y4 + ) { + + double denom = ((y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1)); + + if (denom >= 0 && denom <= 0) { + return false; + } + + double dx1 = x1; + double dy1 = y1; + double dx2 = x2; + double dy2 = y2; + double dx3 = x3; + double dy3 = y3; + double dx4 = x4; + double dy4 = y4; + + double dist_a = ((dx4 - dx3) * (dy1 - dy3) - (dy4 - dy3) * (dx1 - dx3)) / denom; + double dist_b = ((dx2 - dx1) * (dy1 - dy3) - (dy2 - dy1) * (dx1 - dx3)) / denom; + + if ((0 <= dist_a) && (dist_a <= 1) && (0 <= dist_b) && (dist_b <= 1)) { + return true; + } + return false; + +} + +bool common_hal_vectorio_line_rectangle_intersects( + int16_t x1, int16_t y1, int16_t x2, int16_t y2, + int16_t rx, int16_t ry, int16_t rw, int16_t rh + ) { + + + if (common_hal_vectorio_line_line_intersects(x1, y1, x2, y2, + rx, ry, rx, ry + rh)) { + return true; + } + if (common_hal_vectorio_line_line_intersects(x1, y1, x2, y2, + rx + rw, ry, rx + rw, ry + rh)) { + return true; + } + if (common_hal_vectorio_line_line_intersects(x1, y1, x2, y2, + rx, ry, rx + rw, ry)) { + return true; + } + if (common_hal_vectorio_line_line_intersects(x1, y1, x2, y2, + rx, ry + rh, rx + rw, ry + rh)) { + return true; + } + return false; +} + +bool common_hal_vectorio_polygon_rectangle_intersects( + mp_obj_t points_list, int16_t polygon_x, int16_t polygon_y, + int16_t rx, int16_t ry, int16_t rw, int16_t rh + ) { + size_t len = 0; + mp_obj_t *points_list_items; + mp_obj_list_get(points_list, &len, &points_list_items); + bool polygon_contains_point = false; + for (uint16_t i = 0; i < len; i++) { + size_t cur_tuple_len = 0; + mp_obj_t *cur_point_tuple; + mp_arg_validate_type(points_list_items[i], &mp_type_tuple, MP_QSTR_point); + mp_obj_tuple_get(points_list_items[i], &cur_tuple_len, &cur_point_tuple); + + mp_int_t cur_x = mp_arg_validate_type_int(cur_point_tuple[0], MP_QSTR_x) + polygon_x; + mp_int_t cur_y = mp_arg_validate_type_int(cur_point_tuple[1], MP_QSTR_y) + polygon_y; + + size_t next_tuple_len = 0; + mp_obj_t *next_point_tuple; + int next_index = (i + 1) % len; + mp_arg_validate_type(points_list_items[next_index], &mp_type_tuple, MP_QSTR_point); + mp_obj_tuple_get(points_list_items[next_index], &next_tuple_len, &next_point_tuple); + + mp_int_t next_x = mp_arg_validate_type_int(next_point_tuple[0], MP_QSTR_x) + polygon_x; + mp_int_t next_y = mp_arg_validate_type_int(next_point_tuple[1], MP_QSTR_y) + polygon_y; + + if (common_hal_vectorio_line_rectangle_intersects( + cur_x, cur_y, next_x, next_y, + rx, ry, rw, rh + )) { + return true; + } + + if (((cur_y >= ry && ry > next_y) || (cur_y < ry && ry <= next_y)) && + (rx < (next_x - cur_x) * (ry - cur_y) / (next_y - cur_y) + cur_x)) { + + polygon_contains_point = !polygon_contains_point; + } + } + if (polygon_contains_point) { + return true; + } + return false; +} diff --git a/shared-module/vectorio/__init__.h b/shared-module/vectorio/__init__.h index 3db1071653c0..d61990e37c3a 100644 --- a/shared-module/vectorio/__init__.h +++ b/shared-module/vectorio/__init__.h @@ -14,3 +14,6 @@ typedef struct { mp_obj_t obj; event_function *event; } vectorio_event_t; + +float measure_distance( + float x1, float y1, float x2, float y2);