examples/gkurve: fixed logic for points inside polygon

This commit is contained in:
PiergiorgioZagaria 2022-06-05 22:49:28 +02:00 committed by Stephen Gutekanst
parent c1b3996b63
commit 112b837cae

View file

@ -359,30 +359,33 @@ fn uniteOutsideAndInsideVertices(ctx: *OutlineContext) void {
} }
// TODO: Return also allocation error // TODO: Return also allocation error
fn moveToFunction(ctx: *OutlineContext, _to: ft.Vector) ft.Error!void { fn moveToFunction(ctx: *OutlineContext, _to: ft.Vector) ft.Error!void {
// std.log.info("M {} {}", .{ to.x, to.y });
uniteOutsideAndInsideVertices(ctx); uniteOutsideAndInsideVertices(ctx);
const to = Vec2{ @intToFloat(f32, _to.x), @intToFloat(f32, _to.y) }; const to = Vec2{ @intToFloat(f32, _to.x), @intToFloat(f32, _to.y) };
// TODO: Use raycasting of the edges for better accuracy on wether a point is inside the outline or not // To check wether a point is carving a polygon,
const new_point_is_inside = blk: { // Cast a ray to the right of the point and check
if (ctx.outline_verts.items.len == 0) { // when this ray intersects the edges of the polygons,
break :blk false; // if the number of intersections is odd -> inside,
} // if it's even -> outside
var new_point_is_inside = false;
for (ctx.outline_verts.items) |polygon| {
var i: usize = 1;
while (i < polygon.items.len) : (i += 1) {
const v1 = polygon.items[i - 1];
const v2 = polygon.items[i];
var minx: f32 = std.math.f32_max; const min_y = @minimum(v1[1], v2[1]);
var maxx: f32 = std.math.f32_min; const max_y = @maximum(v1[1], v2[1]);
var miny: f32 = std.math.f32_max; const min_x = @minimum(v1[0], v2[0]);
var maxy: f32 = std.math.f32_min;
for (ctx.outline_verts.items[ctx.outline_verts.items.len - 1].items) |item| {
minx = @minimum(item[0], minx);
maxx = @maximum(item[0], maxx);
miny = @minimum(item[1], miny);
maxy = @maximum(item[1], maxy);
}
break :blk (to[0] >= minx) and (to[0] <= maxx) and (to[1] >= miny) and (to[1] <= maxy); // If the point is at the same y as another, it may be counted twice,
}; // That's why we add the last !=
if (to[1] >= min_y and to[1] <= max_y and to[0] >= min_x and to[1] != v2[1]) {
new_point_is_inside = !new_point_is_inside;
}
}
}
// If the point is inside, put it in the inside verts // If the point is inside, put it in the inside verts
if (new_point_is_inside) { if (new_point_is_inside) {