diff --git a/src/application/applicationstate.c b/src/application/applicationstate.c index 5f973fb..c75354d 100644 --- a/src/application/applicationstate.c +++ b/src/application/applicationstate.c @@ -220,6 +220,13 @@ void vektor_appstate_new(VektorWidgetState* wstate, VektorAppState* stateOut) { stateOut->shapeBuffer = malloc(sizeof(VektorShapeBuffer)); *stateOut->shapeBuffer = (VektorShapeBuffer){0}; + + VektorCircle circ = (VektorCircle){.center = (V2){0, 0}, .radius = 0.3}; + VektorShape shp = vektor_shape_new( + (VektorPrimitive){.kind = VEKTOR_CIRCLE, .circle = circ}, + (VektorStyle){.stroke_color = stateOut->currentColor, 0.01}, 0); + vektor_shapebuffer_add_shape(stateOut->shapeBuffer, shp); + stateOut->canvas = malloc(sizeof(VektorCanvas)); stateOut->widgetState = wstate; stateOut->currentColor = vektor_color_solid(0, 0, 0); diff --git a/src/core/primitives.c b/src/core/primitives.c index c659690..568e904 100644 --- a/src/core/primitives.c +++ b/src/core/primitives.c @@ -59,6 +59,21 @@ void vektor_polygon_free(VektorPolygon* pg) { free(pg); } +VektorCircle* vektor_circle_new(void) { + VektorCircle* circ = malloc(sizeof(VektorCircle)); + circ->center = (V2){0, 0}; + circ->radius = 0; + return circ; +} + +void vektor_circle_set_center(VektorCircle* circle, V2 point) { + circle->center = point; +} + +void vektor_circle_set_radius(VektorCircle* circle, double radius) { + circle->radius = radius; +} + VektorRectangle* vektor_rectangle_new(void) { VektorRectangle* rct = malloc(sizeof(VektorRectangle)); rct->start = (V2){.x = 0, .y = 0}; diff --git a/src/core/primitives.h b/src/core/primitives.h index 7897116..8c93193 100644 --- a/src/core/primitives.h +++ b/src/core/primitives.h @@ -53,6 +53,10 @@ VektorPolygon* vektor_polygon_new(void); void vektor_polygon_add_point(VektorPolygon* pl, V2 point); void vektor_polygon_free(VektorPolygon* pl); +VektorCircle* vektor_circle_new(void); +void vektor_circle_set_center(VektorCircle* circle, V2 point); +void vektor_circle_set_radius(VektorCircle* circle, double radius); + VektorRectangle* vektor_rectangle_new(void); void vektor_rectangle_set_end(VektorRectangle* rct, V2 point); void vektor_rectangle_set_start(VektorRectangle* rct, V2 point); @@ -77,6 +81,7 @@ typedef struct { VektorBBox vektor_polyline_get_bbox(VektorPrimitive prim); VektorBBox vektor_polygon_get_bbox(VektorPrimitive prim); +VektorBBox vektor_circle_get_bbox(VektorPrimitive prim); VektorBBox vektor_rectangle_get_bbox(VektorPrimitive prim); VektorBBox vektor_primitive_get_bbox(VektorPrimitive prim); diff --git a/src/core/raster.c b/src/core/raster.c index a2c6350..ae32298 100644 --- a/src/core/raster.c +++ b/src/core/raster.c @@ -3,8 +3,11 @@ #include "primitives.h" #include "src/core/vector.h" #include "stddef.h" +#include #include +#define PI 3.14159265358979323846 + void vektor_edgebuffer_add_edge(EdgeBuffer* buffer, Edge edge) { if (buffer->count >= buffer->capacity) { buffer->capacity = buffer->capacity ? buffer->capacity * 2 : 4; @@ -14,7 +17,7 @@ void vektor_edgebuffer_add_edge(EdgeBuffer* buffer, Edge edge) { } void vektor_polyline_tessellate(EdgeBuffer* buffer, VektorPolyline* line, - size_t j) { + size_t j, double scale) { for (size_t i = 0; i + 1 < line->count; i++) { vektor_edgebuffer_add_edge( buffer, (Edge){line->points[i], line->points[i + 1], 0, j}); @@ -22,7 +25,7 @@ void vektor_polyline_tessellate(EdgeBuffer* buffer, VektorPolyline* line, } void vektor_polygon_tessellate(EdgeBuffer* buffer, VektorPolygon* polygon, - size_t j) { + size_t j, double scale) { for (size_t i = 0; i + 1 < polygon->count; i++) { vektor_edgebuffer_add_edge( buffer, (Edge){polygon->points[i], polygon->points[i + 1], 0, j}); @@ -32,8 +35,23 @@ void vektor_polygon_tessellate(EdgeBuffer* buffer, VektorPolygon* polygon, (Edge){polygon->points[polygon->count - 1], polygon->points[0], 0, j}); } +void vektor_circle_tessellate(EdgeBuffer* buffer, VektorCircle* circle, + size_t j, double scale) { + double err = 0.000025; + size_t res = PI * sqrt((scale * circle->radius) / (2 * err)); + for (size_t i = 0; i < res; i++) { + double theta1 = (2 * PI * i) / res; + double theta2 = (2 * PI * (i + 1)) / res; + V2 p1 = (V2){circle->center.x + circle->radius * cos(theta1), + circle->center.y + circle->radius * sin(theta1)}; + V2 p2 = (V2){circle->center.x + circle->radius * cos(theta2), + circle->center.y + circle->radius * sin(theta2)}; + vektor_edgebuffer_add_edge(buffer, (Edge){p1, p2, 0, j}); + } +} + void vektor_rectangle_tessellate(EdgeBuffer* buffer, VektorRectangle* rct, - size_t j) { + size_t j, double scale) { if (vec2_equals(rct->end, rct->start)) { return; } @@ -49,22 +67,27 @@ void vektor_rectangle_tessellate(EdgeBuffer* buffer, VektorRectangle* rct, vektor_edgebuffer_add_edge(buffer, left); } -void vektor_rasterize(VertexBuffer* vb, VektorShapeBuffer* shapes) { +void vektor_rasterize(VertexBuffer* vb, VektorShapeBuffer* shapes, + double scale) { EdgeBuffer edges = {0}; for (size_t i = 0; i < shapes->count; i++) { VektorPrimitive* p = &shapes->shapes[i].primitive; switch (p->kind) { case VEKTOR_POLYLINE: - vektor_polyline_tessellate(&edges, p->polyline, i); + vektor_polyline_tessellate(&edges, p->polyline, i, scale); break; case VEKTOR_POLYGON: - vektor_polygon_tessellate(&edges, p->polygon, i); + vektor_polygon_tessellate(&edges, p->polygon, i, scale); + break; + + case VEKTOR_CIRCLE: + vektor_circle_tessellate(&edges, &p->circle, i, scale); break; case VEKTOR_RECTANGLE: - vektor_rectangle_tessellate(&edges, &p->rectangle, i); + vektor_rectangle_tessellate(&edges, &p->rectangle, i, scale); break; default: diff --git a/src/core/raster.h b/src/core/raster.h index c93477a..7a675fa 100644 --- a/src/core/raster.h +++ b/src/core/raster.h @@ -24,11 +24,13 @@ typedef struct { void vektor_edgebuffer_add_edge(EdgeBuffer* edges, Edge edge); void vektor_polyline_tessellate(EdgeBuffer* edges, VektorPolyline* line, - size_t i); + size_t i, double scale); void vektor_polygon_tessellate(EdgeBuffer* buffer, VektorPolygon* polygon, - size_t i); + size_t i, double scale); +void vektor_circle_tessellate(EdgeBuffer* buffer, VektorCircle* circle, + size_t i, double scale); void vektor_rectangle_tessellate(EdgeBuffer* buffer, VektorRectangle* rct, - size_t i); + size_t i, double scale); typedef struct { V2 coords; @@ -49,6 +51,7 @@ void vektor_edge_to_triangles(VertexBuffer* vb, Edge e, VektorShapeBuffer* shape_buffer); void vektor_edges_to_triangles(VertexBuffer* vb, EdgeBuffer* edges, VektorShapeBuffer* shape_buffer); -void vektor_rasterize(VertexBuffer* vb, VektorShapeBuffer* shapes); +void vektor_rasterize(VertexBuffer* vb, VektorShapeBuffer* shapes, + double scale); #endif // RASTER_H_ diff --git a/src/ui/vektorcanvas.c b/src/ui/vektorcanvas.c index 35f092e..c10a427 100644 --- a/src/ui/vektorcanvas.c +++ b/src/ui/vektorcanvas.c @@ -138,7 +138,7 @@ static gboolean render(GtkGLArea* a, GdkGLContext* ctx, VektorCanvasRenderInfo* renderInfo) { vb.count = 0; - vektor_rasterize(&vb, renderInfo->shapes); + vektor_rasterize(&vb, renderInfo->shapes, 2); size_t shape_vertex_count = vb.count; // remember how many vertices belong to shapes