Skip to content

Commit

Permalink
Fix the doc comments.
Browse files Browse the repository at this point in the history
Previously I was using two slashes for doc comments. Turns out only three slashes counts as a doc comment! Now it's fixed, we should get proper docs.
  • Loading branch information
andriyDev committed Mar 29, 2024
1 parent 59bca58 commit 4b51313
Show file tree
Hide file tree
Showing 6 changed files with 176 additions and 175 deletions.
12 changes: 6 additions & 6 deletions crates/dodgy_2d/src/common.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
use glam::Vec2;

// Computes the 2D determinant of `a` and `b`, aka the 2D cross product.
/// Computes the 2D determinant of `a` and `b`, aka the 2D cross product.
pub fn determinant(a: Vec2, b: Vec2) -> f32 {
a.x * b.y - a.y * b.x
}

// Computes the "time" along both lines when the lines intersect. If the lines
// are parallel, the result is None. The lines are not line segments; the time
// is allowed to be any number, even negative or greater than one. The resulting
// Vec2 contains the time for line 1 in the x component, and the time for line 2
// in the y component.
/// Computes the "time" along both lines when the lines intersect. If the lines
/// are parallel, the result is None. The lines are not line segments; the time
/// is allowed to be any number, even negative or greater than one. The
/// resulting Vec2 contains the time for line 1 in the x component, and the time
/// for line 2 in the y component.
pub fn time_to_intersect_lines(
line_1_start: Vec2,
line_1_end: Vec2,
Expand Down
53 changes: 27 additions & 26 deletions crates/dodgy_2d/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,47 +38,48 @@ pub use obstacles::Obstacle;
pub use simulator::{AgentParameters, Simulator, SimulatorMargin};
pub use visibility_set::VisibilitySet;

// A single agent in the simulation.
/// A single agent in the simulation.
#[derive(Clone, PartialEq, Debug)]
pub struct Agent {
// The position of the agent.
/// The position of the agent.
pub position: Vec2,
// The current velocity of the agent.
/// The current velocity of the agent.
pub velocity: Vec2,

// The radius of the agent. Agents will use this to avoid bumping into each
// other.
/// The radius of the agent. Agents will use this to avoid bumping into each
/// other.
pub radius: f32,
// The amount of responsibility an agent has to avoid other agents. The
// amount of avoidance between two agents is then dependent on the ratio of
// the responsibility between the agents. Note this does not affect
// avoidance of obstacles.

/// The amount of responsibility an agent has to avoid other agents. The
/// amount of avoidance between two agents is then dependent on the ratio of
/// the responsibility between the agents. Note this does not affect
/// avoidance of obstacles.
pub avoidance_responsibility: f32,
}

// Parameters for computing the avoidance vector.
/// Parameters for computing the avoidance vector.
#[derive(Clone, PartialEq, Debug)]
pub struct AvoidanceOptions {
// The distance that the agent must be from any obstacle. This is commonly
// the agent's radius to ensure the agent never intersects the obstacle (for
// example a wall). An alternative is to set this to a small value to treat
// obstacles as the edge of something (like a cliff).
/// The distance that the agent must be from any obstacle. This is commonly
/// the agent's radius to ensure the agent never intersects the obstacle (for
/// example a wall). An alternative is to set this to a small value to treat
/// obstacles as the edge of something (like a cliff).
pub obstacle_margin: f32,
// How long in the future should collisions be considered between agents.
/// How long in the future should collisions be considered between agents.
pub time_horizon: f32,
// How long in the future should collisions be considered for obstacles.
/// How long in the future should collisions be considered for obstacles.
pub obstacle_time_horizon: f32,
}

impl Agent {
// Computes a velocity based off the agent's preferred velocity (usually the
// direction to its current goal/waypoint). This new velocity is intended to
// avoid running into the agent's `neighbours`. This is not always possible,
// but agents will attempt to resolve any collisions in a reasonable fashion.
// The `max_speed` is the maximum magnitude of the returned velocity. Even if
// the `preferred_velocity` is larger than `max_speed`, the resulting vector
// will be at most `max_speed` in length. The `time_step` helps determine the
// velocity in cases of existing collisions, and must be positive.
/// Computes a velocity based off the agent's preferred velocity (usually the
/// direction to its current goal/waypoint). This new velocity is intended to
/// avoid running into the agent's `neighbours`. This is not always possible,
/// but agents will attempt to resolve any collisions in a reasonable fashion.
/// The `max_speed` is the maximum magnitude of the returned velocity. Even if
/// the `preferred_velocity` is larger than `max_speed`, the resulting vector
/// will be at most `max_speed` in length. The `time_step` helps determine the
/// velocity in cases of existing collisions, and must be positive.
pub fn compute_avoiding_velocity(
&self,
neighbours: &[Cow<'_, Agent>],
Expand Down Expand Up @@ -121,8 +122,8 @@ impl Agent {
)
}

// Creates a line to describe the half-plane of valid velocities that should
// not collide with `neighbour`.
/// Creates a line to describe the half-plane of valid velocities that should
/// not collide with `neighbour`.
fn get_line_for_neighbour(
&self,
neighbour: &Agent,
Expand Down
148 changes: 74 additions & 74 deletions crates/dodgy_2d/src/linear_programming.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,24 +22,24 @@
use crate::determinant;
use glam::Vec2;

// A half-plane to act as a constraint on the linear program. This is
// represented as a point and a direction, where the valid half-plane resides on
// the counter-clockwise side of `direction` and `point`.
/// A half-plane to act as a constraint on the linear program. This is
/// represented as a point and a direction, where the valid half-plane resides
/// on the counter-clockwise side of `direction` and `point`.
#[derive(Clone, Debug)]
pub struct Line {
pub point: Vec2,
// Must always have length = 1
/// Must always have length = 1
pub direction: Vec2,
}

// Solves the linear program defined as finding the value closest to
// `preferred_value` under the constraints that the value has a length less than
// `radius`, and is outside all half-planes defined by `constraints`. If
// satisfying all constraints is infeasible, the non-rigid constraints (i.e.
// `constraints[rigid_constraint_count..]`) are relaxed and the
// least-penetrating value is returned. Note this means that
// `constraints[0..rigid_constraint_count]` must be feasible, else the results
// are undefined.
/// Solves the linear program defined as finding the value closest to
/// `preferred_value` under the constraints that the value has a length less
/// than `radius`, and is outside all half-planes defined by `constraints`. If
/// satisfying all constraints is infeasible, the non-rigid constraints (i.e.
/// `constraints[rigid_constraint_count..]`) are relaxed and the
/// least-penetrating value is returned. Note this means that
/// `constraints[0..rigid_constraint_count]` must be feasible, else the results
/// are undefined.
pub fn solve_linear_program(
constraints: &[Line],
rigid_constraint_count: usize,
Expand Down Expand Up @@ -67,19 +67,19 @@ pub fn solve_linear_program(

const RVO_EPSILON: f32 = 0.00001;

// The definition of the optimal value ignoring all constraints.
/// The definition of the optimal value ignoring all constraints.
enum OptimalValue {
// The best value of the linear program should be the one nearest to this
// point (that satisfies the constraints).
/// The best value of the linear program should be the one nearest to this
/// point (that satisfies the constraints).
Point(Vec2),
// The best value of the linear program should be the one furthest in this
// direction (that satisfies the constraints). This must be a unit vector.
/// The best value of the linear program should be the one furthest in this
/// direction (that satisfies the constraints). This must be a unit vector.
Direction(Vec2),
}

// Solves the linear program restricted to `line`, and within the circle defined
// by `radius`. In addition, all `constraints` are used to further restrict the
// resulting value. The best value is defined by `optimal_value`.
/// Solves the linear program restricted to `line`, and within the circle
/// defined by `radius`. In addition, all `constraints` are used to further
/// restrict the resulting value. The best value is defined by `optimal_value`.
fn solve_linear_program_along_line(
line: &Line,
radius: f32,
Expand Down Expand Up @@ -179,24 +179,24 @@ fn solve_linear_program_along_line(
Ok(line.point + t * line.direction)
}

// The result of the 2D linear program.
/// The result of the 2D linear program.
#[derive(PartialEq, Debug)]
enum LinearProgram2DResult {
// The linear program was feasible and holds the optimal value.
/// The linear program was feasible and holds the optimal value.
Feasible(Vec2),
// The linear program was infeasible.
/// The linear program was infeasible.
Infeasible {
// The index of the line which caused the linear program to be invalid.
/// The index of the line which caused the linear program to be invalid.
index_of_failed_line: usize,
// The value at the time that the linear program was determined to be
// invalid. The value is "partial" in the sense that it is partially
// constrained by the lines prior to `index_of_failed_line`.
/// The value at the time that the linear program was determined to be
/// invalid. The value is "partial" in the sense that it is partially
/// constrained by the lines prior to `index_of_failed_line`.
partial_value: Vec2,
},
}

// Solves the 2D linear program, restricted to the circle defined by `radius`,
// and under `constraints`. The best value is defined by `optimal_value`.
/// Solves the 2D linear program, restricted to the circle defined by `radius`,
/// and under `constraints`. The best value is defined by `optimal_value`.
fn solve_linear_program_2d(
constraints: &[Line],
radius: f32,
Expand Down Expand Up @@ -243,15 +243,15 @@ fn solve_linear_program_2d(
LinearProgram2DResult::Feasible(best_value)
}

// Solves the 3D linear program, after the 2D linear program was determined to
// be infeasible. This effectively finds the first valid value when moving all
// non-rigid half-planes back at the same speed. `radius` limits the magnitude
// of the resulting value. `rigid_constraint_count` determines the constraints
// that will not be moved. These are assumed to be trivially satisfiable (in
// practice these correspond to obstacles in RVO, which can be satisfied by a
// velocity of 0). `index_of_failed_line` and `partial_value` are the results
// from the infeasible 2D program, where `partial_value` is assumed to satisfy
// all `constraints[0..index_of_failed_line]`.
/// Solves the 3D linear program, after the 2D linear program was determined to
/// be infeasible. This effectively finds the first valid value when moving all
/// non-rigid half-planes back at the same speed. `radius` limits the magnitude
/// of the resulting value. `rigid_constraint_count` determines the constraints
/// that will not be moved. These are assumed to be trivially satisfiable (in
/// practice these correspond to obstacles in RVO, which can be satisfied by a
/// velocity of 0). `index_of_failed_line` and `partial_value` are the results
/// from the infeasible 2D program, where `partial_value` is assumed to satisfy
/// all `constraints[0..index_of_failed_line]`.
fn solve_linear_program_3d(
constraints: &[Line],
rigid_constraint_count: usize,
Expand Down Expand Up @@ -769,9 +769,9 @@ mod tests {
assert_vec2_near!(
solve_linear_program_3d(
&constraints,
/*rigid_constraint_count=*/ 0,
/*radius=*/ 2.0,
/*index_of_failed_line=*/ 0,
/* rigid_constraint_count= */ 0,
/* radius= */ 2.0,
/* index_of_failed_line= */ 0,
Vec2::new(0.0, 0.0)
),
// I had to do some math to solve this. This is the point equa-distant
Expand All @@ -791,14 +791,14 @@ mod tests {
},
];

// The first two constraints cannot be relaxed, so (0, 0) is the best value
// (nearest to satisfying the third constraint).
// The first two constraints cannot be relaxed, so (0, 0) is the best
// value (nearest to satisfying the third constraint).
assert_vec2_near!(
solve_linear_program_3d(
&constraints,
/*rigid_constraint_count=*/ 2,
/*radius=*/ 2.0,
/*index_of_failed_line=*/ 2,
/* rigid_constraint_count= */ 2,
/* radius= */ 2.0,
/* index_of_failed_line= */ 2,
Vec2::new(0.0, 0.0)
),
Vec2::new(0.0, 0.0)
Expand All @@ -813,9 +813,9 @@ mod tests {
assert_vec2_near!(
solve_linear_program_3d(
&constraints,
/*rigid_constraint_count=*/ 1,
/*radius=*/ 2.0,
/*index_of_failed_line=*/ 1,
/* rigid_constraint_count= */ 1,
/* radius= */ 2.0,
/* index_of_failed_line= */ 1,
Vec2::new(0.0, 0.0)
),
Vec2::new(-(PI / 8.0).tan(), 0.0)
Expand All @@ -836,8 +836,8 @@ mod tests {
assert_eq!(
solve_linear_program(
Default::default(),
/*rigid_constraint_count=*/ 0,
/*radius=*/ 1.0,
/* rigid_constraint_count= */ 0,
/* radius= */ 1.0,
Vec2::new(0.5, 0.25)
),
Vec2::new(0.5, 0.25)
Expand All @@ -846,8 +846,8 @@ mod tests {
assert_eq!(
solve_linear_program(
Default::default(),
/*rigid_constraint_count=*/ 0,
/*radius=*/ 1.0,
/* rigid_constraint_count= */ 0,
/* radius= */ 1.0,
Vec2::new(1.0, 1.0)
),
Vec2::new(one_over_root_2, one_over_root_2)
Expand All @@ -867,8 +867,8 @@ mod tests {
assert_eq!(
solve_linear_program(
&constraints,
/*rigid_constraint_count=*/ 0,
/*radius=*/ 1.0,
/* rigid_constraint_count= */ 0,
/* radius= */ 1.0,
Vec2::new(-0.1, 0.3)
),
Vec2::new(-0.1, 0.3)
Expand All @@ -878,8 +878,8 @@ mod tests {
assert_eq!(
solve_linear_program(
&constraints,
/*rigid_constraint_count=*/ 0,
/*radius=*/ 1.0,
/* rigid_constraint_count= */ 0,
/* radius= */ 1.0,
Vec2::new(-2.0, 2.0)
),
Vec2::new(-one_over_root_2, one_over_root_2)
Expand All @@ -889,8 +889,8 @@ mod tests {
assert_eq!(
solve_linear_program(
&constraints,
/*rigid_constraint_count=*/ 0,
/*radius=*/ 1.0,
/* rigid_constraint_count= */ 0,
/* radius= */ 1.0,
Vec2::new(2.0, 0.5)
),
Vec2::new(0.5, 0.5)
Expand All @@ -900,8 +900,8 @@ mod tests {
assert_eq!(
solve_linear_program(
&constraints,
/*rigid_constraint_count=*/ 0,
/*radius=*/ 1.0,
/* rigid_constraint_count= */ 0,
/* radius= */ 1.0,
Vec2::new(0.0, -0.5)
),
Vec2::new(0.0, -0.25)
Expand All @@ -911,8 +911,8 @@ mod tests {
assert_eq!(
solve_linear_program(
&constraints,
/*rigid_constraint_count=*/ 0,
/*radius=*/ 1.0,
/* rigid_constraint_count= */ 0,
/* radius= */ 1.0,
Vec2::new(1.0, -0.5)
),
Vec2::new(0.5, -0.25)
Expand All @@ -935,9 +935,9 @@ mod tests {
assert_vec2_near!(
solve_linear_program(
&constraints,
/*rigid_constraint_count=*/ 0,
/*radius=*/ 2.0,
/*preferred_value=*/ Vec2::new(1.0, 1.0)
/* rigid_constraint_count= */ 0,
/* radius= */ 2.0,
/* preferred_value= */ Vec2::new(1.0, 1.0)
),
// I had to do some math to solve this. This is the point equa-distant
// from all three constraint lines.
Expand All @@ -956,14 +956,14 @@ mod tests {
},
];

// The first two constraints cannot be relaxed, so (0, 0) is the best value
// (nearest to satisfying the third constraint).
// The first two constraints cannot be relaxed, so (0, 0) is the best
// value (nearest to satisfying the third constraint).
assert_vec2_near!(
solve_linear_program(
&constraints,
/*rigid_constraint_count=*/ 2,
/*radius=*/ 2.0,
/*preferred_value=*/ Vec2::new(0.0, 0.0)
/* rigid_constraint_count= */ 2,
/* radius= */ 2.0,
/* preferred_value= */ Vec2::new(0.0, 0.0)
),
Vec2::new(0.0, 0.0)
);
Expand All @@ -977,9 +977,9 @@ mod tests {
assert_vec2_near!(
solve_linear_program(
&constraints,
/*rigid_constraint_count=*/ 1,
/*radius=*/ 2.0,
/*preferred_value=*/ Vec2::new(0.0, 0.0)
/* rigid_constraint_count= */ 1,
/* radius= */ 2.0,
/* preferred_value= */ Vec2::new(0.0, 0.0)
),
Vec2::new(-(PI / 8.0).tan(), 0.0)
);
Expand Down
Loading

0 comments on commit 4b51313

Please sign in to comment.