Splitting function completed

This commit is contained in:
2026-05-01 17:44:30 +02:00
parent afd7aa50c4
commit dd64ec648a
2 changed files with 81 additions and 6 deletions

View File

@@ -1,6 +1,7 @@
const rl = @import("raylib");
const c = @import("../common/constants.zig");
const e = @import("../errors.zig");
const st = @import("../common/structures.zig");
const ut = @import("../common/utils.zig");
const Node = @import("node.zig").Node;
@@ -79,6 +80,18 @@ pub const Road = struct {
pub fn collides(self: *const Road, pos: rl.Vector2) bool {
return rl.checkCollisionPointLine(pos, self.nodes[0].pos, self.nodes[1].pos, c.ROAD_SIZE);
}
/// Updates node reference old_node => new node; returns error if old_node does not exist
pub fn updateNodeReference(self: *Road, old_node: *Node, new_node: *Node) !void {
for (0..self.nodes.len) |i| {
if (self.nodes[i] != old_node) continue;
self.nodes[i] = new_node;
return;
}
return e.Entity.NotFound;
}
};
const std = @import("std");
@@ -109,4 +122,7 @@ test "valid road nodes" {
try expect(road.nodes[0].id == 34);
try expect(road.nodes[1].id == 227);
}
}
// TODO tests
// test every case error for every function that can return an error

View File

@@ -288,18 +288,77 @@ pub const Simulator = struct {
}
/// Takes the data about intersections and adds new nodes there alongside with linking existing roads to them
fn splitRoadsByIntersections(self: *Simulator, intersections: []st.IntersectionData, start: *Node, end: *Node) void {
///
/// Important: This function assumes the intersection array is sorted by distance from the start node (ascending)
fn splitRoadsByIntersections(self: *Simulator, intersections: []st.IntersectionData, start: *Node, end: *Node) !void {
if (intersections.len == 0) {
self.road_man.addRoad(self.allocator, start, end) catch |err| {
std.debug.panic("Failed to create a road connecting the origin nodes: {}\n", .{err});
std.debug.panic("Failed creating the road out of origin nodes: {}\n", .{err});
};
return;
}
for (0..intersections.len) |i| {
_ = i; // autofix
// Here we connect the start node with the first intersection node (via road)
const first_node = self.node_man.getSelectedNode(self.allocator, intersections[0].pos) catch |err| {
std.debug.panic("Failed to add the first node of the intersection: {}\n", .{err});
};
self.road_man.addRoad(self.allocator, start, first_node) catch |err| {
std.debug.panic("Failed to add a road of origin (start) node and the first intersection node: {}\n", .{err});
};
for (0..intersections.len) |i| {
const intersection = intersections[i];
// The node created at the point of intersection
const new_node = self.node_man.getSelectedNode(self.allocator, intersection.pos) catch |err| {
std.debug.panic("Failed to create a node based on the intersection index {d}: {}\n", .{
i,
err
});
};
// Pointer to the node that borders the road that was intersected
// This node and the new_node will become nodes for the new road being created
const old_node_of_road = intersection.road.nodes[1];
// The old road that was intersected now borders the new node
// and the old node is removed from the road's end node reference,
// as is the end node's road reference
// So the intersected road loses old node (at the far end) and gets new node that intersects it
intersection.road.updateNodeReference(old_node_of_road, new_node) catch |err| {
std.debug.panic("Failed to update the road's node references: {}\n", .{err});
};
// Now we add the road (to the road list) and references the road at both bounding nodes
self.road_man.addRoad(self.allocator, new_node, old_node_of_road) catch |err| {
std.debug.panic("Failed to create a road of new node and former node of prior intersecting road", .{
err
});
};
// Here we work on creating new roads between intersection nodes and as such because we need nodes
// at 2 different intersections, it means we have to be sure next one exists
if (i == intersections.len - 1) continue;
const next_intersection = self.node_man.getSelectedNode(self.allocator, intersections[i+1].pos) catch |err| {
std.debug.panic("Failed to create node of next intersection (current index={d}: {}\n", .{i, err});
};
// Creating the road connecting current intersection with the next one
self.road_man.addRoad(self.allocator, new_node, next_intersection) catch |err| {
std.debug.panic("Failed to create the road of current and next intersection nodes: {}\n", .{err});
};
}
// Finally we create final road by connecting last intersection node to the end origin node
const final_intersection_pos = intersections[intersections.len - 1].pos;
const final_intersection_node = self.node_man.getSelectedNode(self.allocator, final_intersection_pos) catch |err| {
std.debug.panic("Failed to create node based on last intersection position: {}\n", .{err});
};
self.road_man.addRoad(self.allocator, final_intersection_node, end) catch |err| {
std.debug.panic("Failed to create a road of final intersection and end origin node: {}\n", .{err});
};
}
};