Splitting function completed
This commit is contained in:
@@ -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
|
||||
@@ -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});
|
||||
};
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user