PicoVector: Experimental matrix transforms.

pull/783/head
Phil Howard 2023-08-15 17:34:46 +01:00
rodzic c7d9fe411a
commit 61c9d7e9b6
4 zmienionych plików z 51 dodań i 1 usunięć

Wyświetl plik

@ -9,6 +9,29 @@ namespace pimoroni {
scale);
}
void PicoVector::rotate(std::vector<pretty_poly::contour_t<int>> &contours, Point origin, float angle) {
pretty_poly::mat3_t t2 = pretty_poly::mat3_t::translation(origin.x, origin.y);
pretty_poly::mat3_t t1 = pretty_poly::mat3_t::translation(-origin.x, -origin.y);
angle = 2 * M_PI * (angle / 360.0f);
pretty_poly::mat3_t r = pretty_poly::mat3_t::rotation(angle);
for(auto &contour : contours) {
for(auto i = 0u; i < contour.count; i++) {
contour.points[i] *= t1;
contour.points[i] *= r;
contour.points[i] *= t2;
}
}
}
void PicoVector::translate(std::vector<pretty_poly::contour_t<int>> &contours, Point translation) {
pretty_poly::mat3_t t = pretty_poly::mat3_t::translation(translation.x, translation.y);
for(auto &contour : contours) {
for(auto i = 0u; i < contour.count; i++) {
contour.points[i] *= t;
}
}
}
Point PicoVector::text(std::string_view text, Point origin) {
// TODO: Normalize types somehow, so we're not converting?
pretty_poly::point_t<int> caret = pretty_poly::point_t<int>(origin.x, origin.y);

Wyświetl plik

@ -59,6 +59,9 @@ namespace pimoroni {
return result;
}
void rotate(std::vector<pretty_poly::contour_t<int>> &contours, Point origin, float angle);
void translate(std::vector<pretty_poly::contour_t<int>> &contours, Point translation);
Point text(std::string_view text, Point origin);
void polygon(std::vector<pretty_poly::contour_t<int>> contours, Point origin = Point(0, 0), int scale=65536);

Wyświetl plik

@ -111,6 +111,10 @@ namespace pretty_poly {
contour_t(std::vector<point_t<T>> v) : points(v.data()), count(v.size()) {};
contour_t(point_t<T> *points, unsigned count) : points(points), count(count) {};
// TODO: Make this work, it's so much nicer to use auto point : contour
//point_t<T> *begin() const { return points; };
//point_t<T> *end() const { return points + count * sizeof(point_t<T>); };
rect_t bounds() {
T minx = this->points[0].x, maxx = minx;
T miny = this->points[0].y, maxy = miny;

Wyświetl plik

@ -239,7 +239,11 @@ mp_obj_t VECTOR_polygon(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_ar
int offset_x = 0;
int offset_y = 0;
float angle = 0.0f;
// TODO: We should probably convert this to a full-fat argument parser
// with optional kwargs for translation and rotation
// this is very, very hacky
if(mp_obj_is_int(pos_args[1])) {
offset_x = mp_obj_get_int(pos_args[1]);
lists++;
@ -252,6 +256,12 @@ mp_obj_t VECTOR_polygon(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_ar
num_tuples--;
}
if (mp_obj_is_float(pos_args[3])) {
angle = mp_obj_get_float(pos_args[3]);
lists++;
num_tuples--;
}
std::vector<pretty_poly::contour_t<int>> contours;
for(auto i = 0u; i < num_tuples; i++) {
@ -278,7 +288,17 @@ mp_obj_t VECTOR_polygon(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_ar
contours.push_back({points, t_contour->len});
}
self->vector->polygon(contours, Point(offset_x, offset_y));
// TODO: This is pretty awful
// Translating contours could be another operation
// But it's costly to convert to/from a list of lists of tuples
// Perhaps polygons should be a purely internal C++ concept
// And we could have make_polygon(list(tuple, tuple)) ?
if(angle != 0.0f) {
self->vector->rotate(contours, Point(offset_x, offset_y), angle);
self->vector->polygon(contours, Point(0, 0));
} else {
self->vector->polygon(contours, Point(offset_x, offset_y));
}
for(auto contour : contours) {
delete contour.points;