mirror of https://codeberg.org/topola/topola.git
docs(math): add some function docstrings
This commit is contained in:
parent
346477f498
commit
368caa268f
|
|
@ -16,7 +16,7 @@ pub enum LineIntersection {
|
||||||
Point(Point),
|
Point(Point),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A line in normal form: `x0*y + y0*y + offset = 0`
|
/// A line in the normal form: `x0*y + y0*y + offset = 0`.
|
||||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||||
pub struct NormalLine {
|
pub struct NormalLine {
|
||||||
pub x: f64,
|
pub x: f64,
|
||||||
|
|
@ -57,6 +57,7 @@ impl NormalLine {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Calculate the intersection between two lines.
|
||||||
pub fn intersects(&self, b: &Self) -> LineIntersection {
|
pub fn intersects(&self, b: &Self) -> LineIntersection {
|
||||||
const ALMOST_ZERO: f64 = f64::EPSILON * 16.0;
|
const ALMOST_ZERO: f64 = f64::EPSILON * 16.0;
|
||||||
let (mut a, mut b) = (*self, *b);
|
let (mut a, mut b) = (*self, *b);
|
||||||
|
|
@ -76,7 +77,7 @@ impl NormalLine {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// project the point `pt` onto this line, and generate a new line which is orthogonal
|
/// Project the point `pt` onto this line, and generate a new line which is orthogonal
|
||||||
/// to `self`, and goes through `pt`.
|
/// to `self`, and goes through `pt`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn orthogonal_through(&self, pt: &Point) -> Self {
|
pub fn orthogonal_through(&self, pt: &Point) -> Self {
|
||||||
|
|
@ -98,6 +99,10 @@ impl NormalLine {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Calculates the intersection of two circles, `circle1` and `circle2`.
|
||||||
|
///
|
||||||
|
/// Returns a `Vec` holding zero, one, or two calculated intersection points,
|
||||||
|
/// depending on how many exist.
|
||||||
pub fn intersect_circles(circle1: &Circle, circle2: &Circle) -> Vec<Point> {
|
pub fn intersect_circles(circle1: &Circle, circle2: &Circle) -> Vec<Point> {
|
||||||
let delta = circle2.pos - circle1.pos;
|
let delta = circle2.pos - circle1.pos;
|
||||||
let d = Euclidean::distance(&circle2.pos, &circle1.pos);
|
let d = Euclidean::distance(&circle2.pos, &circle1.pos);
|
||||||
|
|
@ -128,6 +133,10 @@ pub fn intersect_circles(circle1: &Circle, circle2: &Circle) -> Vec<Point> {
|
||||||
[p + r, p - r].into()
|
[p + r, p - r].into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Calculate the intersection between circle `circle` and line segment `segment`.
|
||||||
|
///
|
||||||
|
/// Returns a `Vec` holding zero, one, or two calculated intersection points,
|
||||||
|
/// depending on how many exist.
|
||||||
pub fn intersect_circle_segment(circle: &Circle, segment: &Line) -> Vec<Point> {
|
pub fn intersect_circle_segment(circle: &Circle, segment: &Line) -> Vec<Point> {
|
||||||
let delta: Point = segment.delta().into();
|
let delta: Point = segment.delta().into();
|
||||||
let from = segment.start_point();
|
let from = segment.start_point();
|
||||||
|
|
@ -174,6 +183,8 @@ pub fn intersect_circle_segment(circle: &Circle, segment: &Line) -> Vec<Point> {
|
||||||
v
|
v
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns `true` the point `p` is between the supporting lines of vectors
|
||||||
|
/// `from` and `to`.
|
||||||
pub fn between_vectors(p: Point, from: Point, to: Point) -> bool {
|
pub fn between_vectors(p: Point, from: Point, to: Point) -> bool {
|
||||||
let cross = perp_dot_product(from, to);
|
let cross = perp_dot_product(from, to);
|
||||||
|
|
||||||
|
|
@ -186,20 +197,21 @@ pub fn between_vectors(p: Point, from: Point, to: Point) -> bool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the (directed) angle between the positive X axis and the vector.
|
/// Calculates the (directed) angle between the positive X axis and vector `vector`.
|
||||||
///
|
///
|
||||||
/// The result is measured counterclockwise and normalized into range (-pi, pi] (like atan2).
|
/// The result is measured counterclockwise and normalized into range (-pi, pi] (like atan2).
|
||||||
pub fn vector_angle(vector: Point) -> f64 {
|
pub fn vector_angle(vector: Point) -> f64 {
|
||||||
vector.y().atan2(vector.x())
|
vector.y().atan2(vector.x())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the (directed) angle between two vectors.
|
/// Calculates the (directed) angle between vectors `v1` and `v2`.
|
||||||
///
|
///
|
||||||
/// The result is measured counterclockwise and normalized into range (-pi, pi] (like atan2).
|
/// The result is measured counterclockwise and normalized into range (-pi, pi] (like atan2).
|
||||||
pub fn angle_between(v1: Point, v2: Point) -> f64 {
|
pub fn angle_between(v1: Point, v2: Point) -> f64 {
|
||||||
perp_dot_product(v1, v2).atan2(dot_product(v1, v2))
|
perp_dot_product(v1, v2).atan2(dot_product(v1, v2))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Calculates the perp dot product of vectors `start - reference` and `stop - reference`.
|
||||||
pub fn seq_perp_dot_product(start: Point, stop: Point, reference: Point) -> f64 {
|
pub fn seq_perp_dot_product(start: Point, stop: Point, reference: Point) -> f64 {
|
||||||
let dx1 = stop.x() - start.x();
|
let dx1 = stop.x() - start.x();
|
||||||
let dy1 = stop.y() - start.y();
|
let dy1 = stop.y() - start.y();
|
||||||
|
|
@ -208,12 +220,21 @@ pub fn seq_perp_dot_product(start: Point, stop: Point, reference: Point) -> f64
|
||||||
perp_dot_product((dx1, dy1).into(), (dx2, dy2).into())
|
perp_dot_product((dx1, dy1).into(), (dx2, dy2).into())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Calculates the dot product of vectors `v1` and `v2`.
|
||||||
pub fn dot_product(v1: Point, v2: Point) -> f64 {
|
pub fn dot_product(v1: Point, v2: Point) -> f64 {
|
||||||
v1.x() * v2.x() + v1.y() * v2.y()
|
v1.x() * v2.x() + v1.y() * v2.y()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This is often called [perp dot product](https://mathworld.wolfram.com/PerpDotProduct.html),
|
/// Calculates the perp dot product of vectors `v1` and `v2`.
|
||||||
/// or "2D cross product".
|
///
|
||||||
|
/// This is defined as the dot product of `v1` rotated counterclockwise by 90
|
||||||
|
/// degrees and `v2`. This is the same as the magnitude of the cross product of `v1`
|
||||||
|
/// with `v2`.
|
||||||
|
///
|
||||||
|
/// It is not uncommon in codebases with planar geometry to call the perp dot
|
||||||
|
/// product simply "cross product", ignoring the distinction between vector
|
||||||
|
/// and its magnitude, since the resulting vector is always perpendicular to
|
||||||
|
/// the plane anyway.
|
||||||
pub fn perp_dot_product(v1: Point, v2: Point) -> f64 {
|
pub fn perp_dot_product(v1: Point, v2: Point) -> f64 {
|
||||||
v1.x() * v2.y() - v1.y() * v2.x()
|
v1.x() * v2.y() - v1.y() * v2.x()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue