Files
263-0007-00L-Advanced-Syste…/headers/board.hpp
T
[Quy Anh] «Elliot» Nguyen b86c856e08 Inlining + Reorganization + Roofline
2026-05-19 23:17:44 +02:00

97 lines
3.6 KiB
C++

#pragma once
#include "vector2d.hpp"
struct Obstacle {
Vector2d start; // First endpoint of the obstacle segment.
Vector2d end; // Second endpoint of the obstacle segment.
Vector2d obstacle_v; // Direction vector of the segment: end - start.
double length_sq_inv; // Inverse squared length of the segment, used for projection.
// Default constructor: creates a degenerate obstacle at the origin.
// This is mainly used for array allocation before assigning real obstacles.
Obstacle() : start(0, 0), end(0, 0), obstacle_v(0, 0), length_sq_inv(0.0) {}
// Constructs an obstacle as a finite line segment from s to e.
//
// The segment direction and inverse squared length are precomputed and cached because
// they are reused when projecting pedestrian positions onto the obstacle.
//
// @param s The first endpoint of the obstacle segment.
// @param e The second endpoint of the obstacle segment.
//
Obstacle(Vector2d s, Vector2d e) : start(s), end(e) {
obstacle_v = end - start;
double length_sq = obstacle_v.dot(obstacle_v);
length_sq_inv = length_sq != 0.0 ? 1.0 / length_sq : 0.0;
}
// Flop count: 5 ADDs, 5 MULTs
//
// Finds the point on this finite obstacle segment that is closest to p.
//
// The method projects the vector (p - start) onto the obstacle direction
// vector, then clamps the projection factor to [0, 1] so that the returned
// point lies on the finite segment.
//
// Note : If the obstacle is a single point, meaning start == end, length_sq_inv is zero
// and the method returns start.
//
// @param p The point for which the closest obstacle point is computed.
// @return The closest point on the obstacle segment to p.
//
Vector2d find_nearest_obstacle_point(const Vector2d &p) const {
// # 3 ADDs, 3 MULTs
double projection = (p - start).dot(obstacle_v) * length_sq_inv;
if (projection < 0.0)
projection = 0.0;
else if (projection > 1.0)
projection = 1.0;
// # 2 ADDs, 2 MULTs
return start + obstacle_v * projection;
}
};
struct Board {
double length; // Board length.
double width; // Board width.
Obstacle *obstacles; // Array of obstacles contained in the board.
int n_obstacles; // Total number of obstacles
// Constructs a rectangular board of size length x width.
//
// The input array o contains n user-defined obstacles. The constructor copies
// those obstacles and then appends the two horizontal borders of the board (bottom and top) as additional
// obstacle segments:
//
// bottom: (0, 0) -> (length, 0)
// top: (0, width) -> (length, width)
//
// Note: only the horizontal borders are modeled as obstacles. The vertical
// borders are left open so pedestrians can enter and leave the walkway without
// being affected by repulsive forces from those borders. This is consistent
// with Fig. 2 in the paper, where the horizontal walkway boundaries are
// emphasized but the vertical ends are not shown as walls.
//
// @param l The board length.
// @param w The board width.
// @param n The number of user-defined obstacles in o.
// @param o Array of user-defined obstacles to copy into the board obstacles array.
//
Board(double l, double w, int n, Obstacle *o) : length(l), width(w), n_obstacles(n + 2) {
obstacles = new Obstacle[n + 2];
for (int i = 0; i < n; i++) {
obstacles[i] = o[i];
}
// Board borders: bottom, top.
obstacles[n] = Obstacle(Vector2d(0, 0), Vector2d(l, 0));
obstacles[n + 1] = Obstacle(Vector2d(0, w), Vector2d(l, w));
}
// Releases the dynamically allocated obstacle array.
~Board() { delete[] obstacles; }
};