examples/gkurve: fixed logic for points inside polygon
This commit is contained in:
parent
c1b3996b63
commit
112b837cae
1 changed files with 21 additions and 18 deletions
|
|
@ -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) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue