Intersection sorting implemented

This commit is contained in:
2026-04-08 21:41:08 +02:00
parent a9dd430cc7
commit 288cfd6b50
5 changed files with 65 additions and 20 deletions

View File

@@ -3,6 +3,7 @@ const rl = @import("raylib");
const c = @import("constants.zig");
const st = @import("structures.zig");
const utils = @import("utils.zig");
const NodeManager = @import("infrastructure/node_manager.zig").NodeManager;
const RoadManager = @import("infrastructure/road_manager.zig").RoadManager;
@@ -19,8 +20,6 @@ pub const Simulator = struct {
display_details: bool,
/// Tracks whether to automatically start build a new road after the creation of previous one is finished
auto_continue: bool,
/// Displays intersection data for easier implementation and debugging
debug_intersection_data: std.ArrayList(st.IntersectionData),
mode: st.Mode,
pub fn init(allocator: std.mem.Allocator) !Simulator {
@@ -30,7 +29,6 @@ pub const Simulator = struct {
.road_man = try .init(allocator),
.display_details = false,
.auto_continue = false,
.debug_intersection_data = .empty,
.mode = .VISUAL,
};
}
@@ -38,7 +36,6 @@ pub const Simulator = struct {
pub fn deinit(self: *Simulator) void {
self.node_man.deinit(self.allocator);
self.road_man.deinit(self.allocator);
self.debug_intersection_data.deinit(self.allocator);
}
/// Input handling function that is exposed to the public
@@ -53,7 +50,6 @@ pub const Simulator = struct {
self.auto_continue = rl.isKeyDown(.left_control);
if (rl.isKeyReleased(.c) and self.mode == .DELETE) {
self.debug_intersection_data.clearRetainingCapacity();
self.node_man.temp_node = null;
self.road_man.roads.clearRetainingCapacity();
self.node_man.clear(self.allocator);
@@ -104,9 +100,16 @@ pub const Simulator = struct {
};
// get intersections made
self.getIntersectingRoads(temp, node) catch |err| {
const data = self.getIntersectingRoads(self.allocator, temp, node) catch |err| {
std.debug.panic("Failed to save intersection data: {}\n", .{err});
};
defer self.allocator.free(data);
std.debug.print("Displaying intersection points in order from start (temp):\n", .{});
for (0..data.len) |i| {
std.debug.print("{d}: ({d}, {d})\n", .{i+1, data[i].point.x, data[i].point.y});
}
std.debug.print("\n", .{});
self.node_man.temp_node = if (self.auto_continue) node else null;
}
@@ -127,11 +130,6 @@ pub const Simulator = struct {
self.node_man.draw(self.display_details);
self.drawUI();
// Display intersection 'nodes'
for (self.debug_intersection_data.items) |intersection| {
rl.drawCircleV(intersection.point, c.NODE_RADIUS / 2, .red);
}
rl.clearBackground(.light_gray);
}
@@ -167,25 +165,44 @@ pub const Simulator = struct {
}
/// Gets list of pointers of all roads that 'collide' with the road bounded by the nodes we pass into it
fn getIntersectingRoads(self: *Simulator, start: *const Node, end: *const Node) !void {
fn getIntersectingRoads(self: *Simulator, allocator: std.mem.Allocator, start: *const Node, end: *const Node) ![]st.IntersectionData {
var intersections: std.ArrayList(st.IntersectionData) = .empty;
var collision_point: rl.Vector2 = undefined;
outer: for (self.road_man.roads.items) |*road| {
if (!rl.checkCollisionLines(start.pos, end.pos, road.nodes[0].pos, road.nodes[1].pos, &collision_point)) continue;
const intersection = st.IntersectionData {
// If there is no collision check the next road
if (!rl.checkCollisionLines(
start.pos,
end.pos,
road.nodes[0].pos,
road.nodes[1].pos,
&collision_point)) continue;
// Save the collision info
const data = st.IntersectionData {
.road = road,
.point = collision_point,
};
const node: Node = .init(0, intersection.point);
const node: Node = .init(0, data.point);
// here we need to check if the points captured already are already within the reach
for (self.debug_intersection_data.items) |collision| {
for (intersections.items) |collision| {
if (node.withinSnappingRadius(collision.point))
continue :outer;
}
if (self.node_man.getNodeWithinRadius(intersection.point) == null) try self.debug_intersection_data.append(self.allocator, intersection);
// This checks whether our collision point is actually to close to the existing node(s)
// to form another intersection there
if (self.node_man.getNodeWithinRadius(data.point) != null) continue;
try intersections.append(self.allocator, data);
}
// we must sort the items by the distance from the first (usually temp) node
const sorted_intersections = try intersections.toOwnedSlice(allocator);
std.sort.block(st.IntersectionData, sorted_intersections, start, utils.compareIntersections);
return sorted_intersections;
}
pub fn update(self: *Simulator) void {