Splitting function completed
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
const rl = @import("raylib");
|
const rl = @import("raylib");
|
||||||
|
|
||||||
const c = @import("../common/constants.zig");
|
const c = @import("../common/constants.zig");
|
||||||
|
const e = @import("../errors.zig");
|
||||||
const st = @import("../common/structures.zig");
|
const st = @import("../common/structures.zig");
|
||||||
const ut = @import("../common/utils.zig");
|
const ut = @import("../common/utils.zig");
|
||||||
const Node = @import("node.zig").Node;
|
const Node = @import("node.zig").Node;
|
||||||
@@ -79,6 +80,18 @@ pub const Road = struct {
|
|||||||
pub fn collides(self: *const Road, pos: rl.Vector2) bool {
|
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);
|
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");
|
const std = @import("std");
|
||||||
@@ -110,3 +123,6 @@ test "valid road nodes" {
|
|||||||
try expect(road.nodes[0].id == 34);
|
try expect(road.nodes[0].id == 34);
|
||||||
try expect(road.nodes[1].id == 227);
|
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
|
/// 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) {
|
if (intersections.len == 0) {
|
||||||
self.road_man.addRoad(self.allocator, start, end) catch |err| {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (0..intersections.len) |i| {
|
// Here we connect the start node with the first intersection node (via road)
|
||||||
_ = i; // autofix
|
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