feat: add circles

This commit is contained in:
2026-03-10 15:36:19 +00:00
parent 143a33558d
commit 22b6700768
6 changed files with 65 additions and 12 deletions

View File

@@ -220,6 +220,13 @@ void vektor_appstate_new(VektorWidgetState* wstate, VektorAppState* stateOut) {
stateOut->shapeBuffer = malloc(sizeof(VektorShapeBuffer)); stateOut->shapeBuffer = malloc(sizeof(VektorShapeBuffer));
*stateOut->shapeBuffer = (VektorShapeBuffer){0}; *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->canvas = malloc(sizeof(VektorCanvas));
stateOut->widgetState = wstate; stateOut->widgetState = wstate;
stateOut->currentColor = vektor_color_solid(0, 0, 0); stateOut->currentColor = vektor_color_solid(0, 0, 0);

View File

@@ -59,6 +59,21 @@ void vektor_polygon_free(VektorPolygon* pg) {
free(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* vektor_rectangle_new(void) {
VektorRectangle* rct = malloc(sizeof(VektorRectangle)); VektorRectangle* rct = malloc(sizeof(VektorRectangle));
rct->start = (V2){.x = 0, .y = 0}; rct->start = (V2){.x = 0, .y = 0};

View File

@@ -53,6 +53,10 @@ VektorPolygon* vektor_polygon_new(void);
void vektor_polygon_add_point(VektorPolygon* pl, V2 point); void vektor_polygon_add_point(VektorPolygon* pl, V2 point);
void vektor_polygon_free(VektorPolygon* pl); 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); VektorRectangle* vektor_rectangle_new(void);
void vektor_rectangle_set_end(VektorRectangle* rct, V2 point); void vektor_rectangle_set_end(VektorRectangle* rct, V2 point);
void vektor_rectangle_set_start(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_polyline_get_bbox(VektorPrimitive prim);
VektorBBox vektor_polygon_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_rectangle_get_bbox(VektorPrimitive prim);
VektorBBox vektor_primitive_get_bbox(VektorPrimitive prim); VektorBBox vektor_primitive_get_bbox(VektorPrimitive prim);

View File

@@ -3,8 +3,11 @@
#include "primitives.h" #include "primitives.h"
#include "src/core/vector.h" #include "src/core/vector.h"
#include "stddef.h" #include "stddef.h"
#include <math.h>
#include <stddef.h> #include <stddef.h>
#define PI 3.14159265358979323846
void vektor_edgebuffer_add_edge(EdgeBuffer* buffer, Edge edge) { void vektor_edgebuffer_add_edge(EdgeBuffer* buffer, Edge edge) {
if (buffer->count >= buffer->capacity) { if (buffer->count >= buffer->capacity) {
buffer->capacity = buffer->capacity ? buffer->capacity * 2 : 4; 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, 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++) { for (size_t i = 0; i + 1 < line->count; i++) {
vektor_edgebuffer_add_edge( vektor_edgebuffer_add_edge(
buffer, (Edge){line->points[i], line->points[i + 1], 0, j}); 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, 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++) { for (size_t i = 0; i + 1 < polygon->count; i++) {
vektor_edgebuffer_add_edge( vektor_edgebuffer_add_edge(
buffer, (Edge){polygon->points[i], polygon->points[i + 1], 0, j}); 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}); (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, void vektor_rectangle_tessellate(EdgeBuffer* buffer, VektorRectangle* rct,
size_t j) { size_t j, double scale) {
if (vec2_equals(rct->end, rct->start)) { if (vec2_equals(rct->end, rct->start)) {
return; return;
} }
@@ -49,22 +67,27 @@ void vektor_rectangle_tessellate(EdgeBuffer* buffer, VektorRectangle* rct,
vektor_edgebuffer_add_edge(buffer, left); 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}; EdgeBuffer edges = {0};
for (size_t i = 0; i < shapes->count; i++) { for (size_t i = 0; i < shapes->count; i++) {
VektorPrimitive* p = &shapes->shapes[i].primitive; VektorPrimitive* p = &shapes->shapes[i].primitive;
switch (p->kind) { switch (p->kind) {
case VEKTOR_POLYLINE: case VEKTOR_POLYLINE:
vektor_polyline_tessellate(&edges, p->polyline, i); vektor_polyline_tessellate(&edges, p->polyline, i, scale);
break; break;
case VEKTOR_POLYGON: 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; break;
case VEKTOR_RECTANGLE: case VEKTOR_RECTANGLE:
vektor_rectangle_tessellate(&edges, &p->rectangle, i); vektor_rectangle_tessellate(&edges, &p->rectangle, i, scale);
break; break;
default: default:

View File

@@ -24,11 +24,13 @@ typedef struct {
void vektor_edgebuffer_add_edge(EdgeBuffer* edges, Edge edge); void vektor_edgebuffer_add_edge(EdgeBuffer* edges, Edge edge);
void vektor_polyline_tessellate(EdgeBuffer* edges, VektorPolyline* line, void vektor_polyline_tessellate(EdgeBuffer* edges, VektorPolyline* line,
size_t i); size_t i, double scale);
void vektor_polygon_tessellate(EdgeBuffer* buffer, VektorPolygon* polygon, 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, void vektor_rectangle_tessellate(EdgeBuffer* buffer, VektorRectangle* rct,
size_t i); size_t i, double scale);
typedef struct { typedef struct {
V2 coords; V2 coords;
@@ -49,6 +51,7 @@ void vektor_edge_to_triangles(VertexBuffer* vb, Edge e,
VektorShapeBuffer* shape_buffer); VektorShapeBuffer* shape_buffer);
void vektor_edges_to_triangles(VertexBuffer* vb, EdgeBuffer* edges, void vektor_edges_to_triangles(VertexBuffer* vb, EdgeBuffer* edges,
VektorShapeBuffer* shape_buffer); VektorShapeBuffer* shape_buffer);
void vektor_rasterize(VertexBuffer* vb, VektorShapeBuffer* shapes); void vektor_rasterize(VertexBuffer* vb, VektorShapeBuffer* shapes,
double scale);
#endif // RASTER_H_ #endif // RASTER_H_

View File

@@ -138,7 +138,7 @@ static gboolean render(GtkGLArea* a, GdkGLContext* ctx,
VektorCanvasRenderInfo* renderInfo) { VektorCanvasRenderInfo* renderInfo) {
vb.count = 0; vb.count = 0;
vektor_rasterize(&vb, renderInfo->shapes); vektor_rasterize(&vb, renderInfo->shapes, 2);
size_t shape_vertex_count = size_t shape_vertex_count =
vb.count; // remember how many vertices belong to shapes vb.count; // remember how many vertices belong to shapes